Polycarpus enjoys studying Berland hieroglyphs. Once Polycarp got hold of two ancient Berland pictures, on each of which was drawn a circle of hieroglyphs. We know that no hieroglyph occurs twice in either the first or the second circle (but in can occur once in each of them).Polycarpus wants to save these pictures on his laptop, but the problem is, laptops do not allow to write hieroglyphs circles. So Polycarp had to break each circle and write down all of its hieroglyphs in a clockwise order in one line. A line obtained from the first circle will be called a, and the line obtained from the second one will be called b.There are quite many ways to break hieroglyphic circles, so Polycarpus chooses the method, that makes the length of the largest substring of string a, which occurs as a subsequence in string b, maximum.Help Polycarpus — find the maximum possible length of the desired substring (subsequence) if the first and the second circles are broken optimally.The length of string s is the number of characters in it. If we denote the length of string s as |s|, we can write the string as s = s1s2... s|s|.A substring of s is a non-empty string x = s[a... b] = sasa + 1... sb (1 ≤ a ≤ b ≤ |s|). For example, "code" and "force" are substrings of "codeforces", while "coders" is not. A subsequence of s is a non-empty string y = s[p1p2... p|y|] = sp1sp2... sp|y| (1 ≤ p1 < p2 < ... < p|y| ≤ |s|). For example, "coders" is a subsequence of "codeforces".

The first line contains two integers la and lb (1 ≤ la, lb ≤ 1000000) — the number of hieroglyphs in the first and second circles, respectively. Below, due to difficulties with encoding of Berland hieroglyphs, they are given as integers from 1 to 106. The second line contains la integers — the hieroglyphs in the first picture, in the clockwise order, starting with one of them. The third line contains lb integers — the hieroglyphs in the second picture, in the clockwise order, starting with one of them. It is guaranteed that the first circle doesn't contain a hieroglyph, which occurs twice. The second circle also has this property.

Print a single number — the maximum length of the common substring and subsequence. If at any way of breaking the circles it does not exist, print 0.

NoteIn the first test Polycarpus picks a string that consists of hieroglyphs 5 and 1, and in the second sample — from hieroglyphs 1, 3 and 5.

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

const int maxn = 1000009;

int a[maxn], b[maxn];
int pos_in_b[maxn];
int Q[2 * maxn];

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);

    for (int i = 0; i < n; i++) scanf("%d", a + i);
    for (int i = 0; i < m; i++) scanf("%d", b + i);

    memset(pos_in_b, -1, sizeof pos_in_b);
    for (int i = 0; i < m; i++) pos_in_b[b[i]] = i;

    int c = 0;
    int ql = 0, qr = 0;

    int ans = 0;

    for (int r = 0, l = 0; r < 2 * n - 1; r++) {
        int pos = pos_in_b[a[r % n]];
        if (pos == -1) {
            l = r + 1;
            ql = qr = 0;
            continue;
        }

        if (qr > ql && Q[qr - 1] >= pos + c)
            c += m;

        Q[qr++] = pos + c;

        while (r - l + 1 > n || Q[qr - 1] - Q[ql] + 1 > m) {
            l++;
            ql++;
        }

        ans = max(ans, r - l + 1);
    }

    printf("%d", ans);
}

#if 1
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <functional>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <ctime>
#include <cassert>
#include <sstream>
#include <iostream>
#include <bitset>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int , int> pii;
typedef vector <int> veci;
typedef vector <veci> graph;
const LD eps = 1e-9;
const LD pi = acos(-1.0);
const int inf = 1000 * 1000 * 1000;
const LL inf64 = LL(inf) * inf;

#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define iss istringstream
#define oss ostringstream
#define dbg(x) {cerr << #x << " = " << x << endl;}
#define dbgv(x) {cerr << #x << " ={"; for (int _i = 0; _i < x.size(); _i++) {if (_i) cerr << ", "; cerr << x[_i];} cerr << "}" << endl;}
#define NAME "problem"

const int maxn = 2000000;
LL q[maxn];
int ql, qr;
int a[2*maxn], b[maxn];
int pos[maxn];

void gen()
{
	freopen("input.txt", "w", stdout);
	int n = 1000000;
	vector<int> p(n);
	for(int i = 1; i <+ n; ++i)
		p[i - 1] = i;
	cout << n << " " << n << endl;
	random_shuffle(p.begin(), p.end());
	for(int i = 0; i < n; ++i)
		printf("%d ", p[i]);
	printf("\n");
	random_shuffle(p.begin(), p.end());
	for(int i = 0; i < n; ++i)
		printf("%d ", p[i]);
	printf("\n");
	exit(0);
}
int main()
{
//	gen();
//	freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout);
	//freopen(NAME ".in","r",stdin);freopen(NAME ".out","w",stdout);

	clock_t tstart = clock();
	int n, m;
	cin >> n >> m;

	for(int i = 0; i < n; ++i)
	{
		scanf("%d", &a[i]);
		a[i]--;
		a[i + n] = a[i];
	}

	for(int i = 0; i < m; ++i)
	{
		scanf("%d", &b[i]);
		b[i]--;
	}

	memset(pos, -1, sizeof pos);

	for(int i = 0; i < m; ++i)
		pos[b[i]] = i;

	int best = 0;
	int l = 0, r = -1;

//	deque<int> q;
	ql = qr = 0;

	for(int i = 0; i < 2 * n; ++i)
	{
//		cerr << i << endl;
		if(r < l)
		{
			if(pos[a[i]] != -1)
			{
				l = r = i;
				ql = qr = 0;
				q[qr++] = (pos[a[i]]);
			}
		} else
		{
			if(pos[a[i]] == -1)
			{
				l = 0;
				r = -1;
				ql = qr = 0;
				continue;
			}
			if(pos[a[i]] > q[qr - 1])
			{

				q[qr++] = (pos[a[i]]);
				r++;
			} else
			{
				LL z = LL(q[qr - 1] / m) * m + pos[a[i]];
				while(z < q[qr - 1])
					z += m;
				q[qr++] = z;
				r++;
			}
			while(ql != qr && q[qr - 1] - q[ql]>= m)
			{
				ql++;
				l++;
			}

		}

//		cerr << l << " " << r << endl;
//		if(q.size())
//			cerr << "#" << q.front() << " " << q.back() << endl;
		best = max(best, r - l + 1);
	}

	best = min(best, n);
	best = min(best, m);
	cout << best << endl;

	dbg((clock() - tstart) / LD(CLOCKS_PER_SEC));

	return 0;
}
/*************************
*************************/
#endif

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>

#define MAXN 1000000

using namespace std;

int L1, L2;
int v[MAXN + 1], pos[MAXN + 1];

bool valid(int p, int q, int nq)
{
	if(nq == -1) return 0;
	else
	{
		if(p > q) q += L2;
		if(q > nq) nq += L2;

		return p <= q && q <= nq && nq - p < L2;
	}
}

int main()
{
	while(scanf("%d %d", &L1, &L2) == 2)
	{
		for(int i=0; i<L1; i++)
			scanf("%d", &v[i]);

		memset(pos, -1, sizeof(pos));

		for(int i=0; i<L2; i++)
		{
			int tmp;
			scanf("%d", &tmp);
			pos[tmp] = i;
		}

		int i = 0, j = 0;
		int p = pos[v[0]], q = pos[v[0]];
		int maxN = (p != -1);

		while(i < L1)
		{
			p = pos[v[i]];

			if(p != -1)
			{
				if(j < i)
				{
					j = i;
					q = pos[v[j%L1]];
				}

				while(j + 1 - i < L1 && valid(p, q, pos[v[(j+1)%L1]]))
				{
					j = j + 1;
					q = pos[v[j%L1]];
					maxN = max(maxN, j-i+1);
				}
			}

			i++;
		}

		cout<<maxN<<endl;
	}

	return 0;
}

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <memory.h>
#define vc vector
#define pr pair
#define mp make_pair
#define sz(x) x.size()
#define For(i,s,e,p) for(int i=(s);i<=(e);i+=(p))
#define Rep(i,n) For(i,0,n-1,1)
#define Set(A,x) memset(A, x, sizeof(A))
#define Clear(A) Set(A, 0)

using namespace std;
vector<int> A, B;
int W[1000001];
int main() {
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	int n, m;
	scanf("%d %d",&n,&m);
	int i, j;
	for(i=0;i<n;i++){
		int x;
		scanf("%d",&x);
		x--;
		A.push_back(x);
	}
	for(i=0;i<1000000;i++) W[i] = -1;
	for(i=0;i<m;i++){
		int x;
		scanf("%d",&x);
		x--;
		B.push_back(x);
		W[x] = i;
	}
	int l = 0;
	int sol = 0;
	for(i=0,j=0;i<n;i++){
		for(;j<n;j++){
			int p = (i+j) % n;
			int x = W[ A[p] ];
			if (x == -1) break;
			if (j == 0) {
				l = 0;
			}
			else if (j > 0){
				int bef;
				bef = (i+j-1)%n;
				int bx = W[ A[bef] ];
				int g = x - bx;
				if (g < 0) g += m;
				if (l + g >= m) break;
				l += g;
			}
		}
		if (j > sol) sol = j;
		if (j > 0) {
			if (j > 1 && i+1 < n) {
				int a = A[i];
				int b = A[i+1];
				int d = W[b] - W[a];
				if (d < 0) d += m;
				l -= d;
			}
			j--;
		}
	}
	printf("%d\n", sol);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int p[1000010],a[1000010],n,m,ans;
deque<int>q;
bool in(int x,int L,int R){
    if(L<=R)return L<=x&&x<=R;
    else return x<=R||L<=x;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)scanf("%d",&a[i]);
    memset(p,-1,sizeof p);
    for(int i=0,x;i<m;++i){
        scanf("%d",&x);
        p[x]=i;
    }
    for(int i=0;i<n+n;++i){
        if(p[a[i%n]]==-1){
            q.clear();
            continue;
        }
        while(!q.empty()&&in(p[a[i%n]],q.front(),q.back()))q.pop_front();
        q.push_back(p[a[i%n]]);
        ans=max(ans,(int)q.size());
    }
    printf("%d\n",ans);
    return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int MAXN = 1 << 20;

int a[MAXN], b[MAXN];
long long c[MAXN + MAXN];

unordered_map<int, int> mp(MAXN);

int main() {
    int n, m, ans = 0;

    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < m; ++i) {
        scanf("%d", &b[i]);
        mp[b[i]] = i;
    }
    for (int i = 0; i < n; ++i) {
        c[i] = mp.count(a[i]) > 0 ? mp[a[i]] : -1;
    }
    copy(c, c + n, c + n);
    for (int i = 1; i < n + n; ++i) {
        if (c[i] != -1 && c[i - 1] != -1 && c[i] <= c[i - 1]) {
            c[i] += ((c[i - 1] - c[i]) / m + 1) * m;
        }
    }
    for (int i = 0, j = 0; i < n; ++i) {
        j = max(i, j);
        while (c[j] != -1 && c[j] - c[i] < m) {
            ++j;
            ans = max(ans, j - i);
        }
        if (c[j] == -1) {
            i = j;
        }
    }
    printf("%d\n", ans);

    return 0;
}

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <deque>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int n, m;
int seq[1000010];
int rev[1000010];
int mapto[1000010];

inline int D(int next, int prev) {
  int d = rev[next % n] - rev[prev % n];
  if (d < 0) { d += m; }
  return d;
}

int main() {
  while (scanf("%d %d", &n, &m) > 0) {
    MEMSET(mapto, -1);
    MEMSET(rev, -1);
    {
      REP(i, n) {
        int v = 0;
        scanf("%d", &v);
        mapto[v] = i;
      }
      int cnt = 0;
      REP(i, m) {
        int v;
        scanf("%d", &v);
        if (mapto[v] == -1) { continue; }
        v = mapto[v];
        rev[v] = cnt;
        seq[cnt++] = v;
      }
      m = cnt;
    }

    int ans = 0;
    int head = 0;
    int tail = 0;
    int len = 0;
    while (tail < n) {
      if (rev[head % n] == -1) {
        len = 0;
        tail = head + 1;
        head = head + 1;
        continue;
      }
      if (head - tail == 0) {
        head++;
      } else {
        len += D(head, head - 1);
        head++;
        while (len > m) {
          tail++;
          len -= D(tail, tail - 1);
        }
      }
      ans = max(ans, head - tail);
      if (ans == m) { break; }
    }
    printf("%d\n", ans);
  }
}

#pragma comment(linker, "/STACK:64000000")
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <sstream>
#include <string.h>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define for1(i, n) for (int i = 1; i <= int(n); i++)
#define forv(i, v) forn(i, v.size())

#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair

#define CIN_FILE "input.txt"
#define COUT_FILE "output.txt"

#define pi 3.1415926535897932

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define NMAX 1000006

int la, lb;
int a[NMAX], b[NMAX];
int posb[NMAX];
ll c[2 * NMAX];

int main()
{

    scanf("%d %d", &la, &lb);

    forn(i, la) scanf("%d", &a[i]);
    forn(i, lb) scanf("%d", &b[i]);

    memset(posb, -1, sizeof(posb));

    forn(i, lb)
    {
        posb[b[i]] = i;
    }

    ll rp = 0;
    forn(i, 2 * la)
    {
        int i1 = i % la;
        if (i == 0 || posb[a[i1]] == -1)
        {
            c[i] = posb[a[i1]];
        }
        else if (posb[a[i1]] + rp > c[i - 1])
        {
            c[i] = posb[a[i1]] + rp;
        }
        else
        {
            rp += lb;
            c[i] = posb[a[i1]] + rp;
        }
    }

    int ans = 0;

    int r = 0;
    forn(l, la)
    {
        if (c[l] == -1)
        {
            continue;
        }
        if (r < l) r = l;

        while (r < 2 * la && c[r] != -1 && c[r] - c[l] < lb) r++;

        ans = max(ans, r - l);

    }

    cout << ans << endl;
    return 0;
}

#include <cstring>
#include <algorithm>
#include <bitset>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template<typename T> void upto(T& a, const T& b) { if (a < b) a = b; }
template<typename T> void dnto(T& a, const T& b) { if (a > b) a = b; }
pii operator +(const pii& a, const pii& b) { return pii(a.first+b.first, a.second+b.second); }
pii operator -(const pii& a, const pii& b) { return pii(a.first-b.first, a.second-b.second); }
ll operator *(const pii& a, const pii& b) { return (ll)a.first*b.first + (ll)a.second*b.second; }
ll operator %(const pii& a, const pii& b) { return (ll)a.first*b.second - (ll)a.second*b.first; }

int n, m;
int trans[1000000 + 1];
int inc[2000000];
int inc_size;
int c[2000000 + 1];
int belong[2000000 + 1];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        int tmp;
        scanf("%d", &tmp);
        trans[tmp] = i + 1;
    }

    for (int i = 0; i < m; i++) {
        int tmp;
        scanf("%d", &tmp);
        if (trans[tmp])
            inc[inc_size++] = trans[tmp];
    }

    if (inc_size == 0) {
        printf("%d\n", 0);
        return 0;
    }

    for (int i = 0; i < inc_size; i++) {
        inc[i + inc_size] = inc[i];// + n;
    }

    //for (int i = 0; i < inc_size * 2; i++) {
        //printf("%d,", inc[i]);
    //}
    //printf("\n");

    int ans = 0;

    for (int i = 0; i < inc_size; i++) {
        int x = inc[i];
        if (belong[x - 1] == 0 && belong[x + n - 1] == 0) {
            belong[x] = x;
            c[x] = 1;
            upto(ans, 1);
        } else {
            int b = (belong[x - 1] ? belong[x - 1] : belong[x + n - 1]);
            belong[x] = b;
            c[b]++;
            upto(ans, c[b]);
        }
    }
        //printf("%d\n", ans);

    for (int i = inc_size; i < inc_size * 2; i++) {
        int x = inc[i];
        int y = inc[i - inc_size];

        c[belong[y]]--;
        belong[y] = 0;

        if (belong[x - 1] == 0 && belong[x + n - 1] == 0) {
            belong[x] = x;
            c[x] = 1;
            upto(ans, 1);
        } else {
            int b = (belong[x - 1] ? belong[x - 1] : belong[x + n - 1]);
            belong[x] = b;
            c[b]++;
            upto(ans, c[b]);
        }
    }

    printf("%d\n", ans);

    return 0;
}

#pragma comment (linker, "/STACK:200000000")
#define _CRT_SECURE_NO_DEPRECATE
#define _SECURE_SCL 0
#include <algorithm>
#include <bitset>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <stack>
#include <sstream>
#include <vector>

using namespace std;

typedef long long int64;
const int INF = (int) 1E9;
const int64 INF64 = (int64) 1E18;
const double EPS = 1E-9;
const double PI = acos((double)0) * 2;

#define forn(i,n)  for (int i=0; i<int(n); ++i)
#define ford(i,n)  for (int i=int(n)-1; i>=0; --i)
#define fore(i,l,n)  for (int i=int(l); i<int(n); ++i)
#define all(a)  a.begin(), a.end()
#define fs  first
#define sc  second
#define pb  push_back
#define mp  make_pair

const int MAXN = 1100*1000;

int n, m, a[MAXN], b[MAXN];

bool read() {
    if (! (cin >> n >> m))
        return false;
    forn(i,n)
        scanf ("%d", &a[i]);
    forn(j,m)
        scanf ("%d", &b[j]);
    return true;
}

int bpos[MAXN], q[MAXN*3], qh, qt;

void solve() {
    memset (bpos, -1, sizeof bpos);
    forn(i,m)
        bpos[b[i]] = i;

    int r = -1,  len = 0,  ans = 0;
    qh = qt = 0;
    bool overlap = false;
    forn(l,n) {
        if (len == 0)
            r = (l-1+n)%n;
        while (len < n) {
            int ch = a[(r+1)%n];
            if (bpos[ch] == -1)  break;

            if (len > 0 && bpos[ch] < q[qt-1]) {
                if (overlap)  break;
                if (bpos[ch] > q[qh])  break;
                overlap = true;
            }
            if (len > 0 && overlap && bpos[ch] > q[qh])  break;

            q[qt++] = bpos[ch];
            r = (r+1)%n;
            ++len;
        }

        ans = max (ans, len);

        if (len > 0) {
            if (len>=2 && q[qh] > q[qh+1])
                overlap = false;
            --len,  ++qh;
            if (len <= 1)
                overlap = false;
        }
    }
    cout << ans << endl;
}

int main() {
#ifdef SU2_PROJ
    freopen ("input.txt", "rt", stdin);
    freopen ("output.txt", "wt", stdout);
    while (read())
        solve();
#else
    if (!read())  throw;
    solve();
#endif
}

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

const int maxn = 1e6*2+5;
int n,m;
int a[maxn];
int b[maxn];
int c[maxn];
int main()
{
    memset(c,-1,sizeof(c));
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(int i=0;i<m;i++)
    {
        scanf("%d",&b[i]);
        c[b[i]]=i;
    }
    int ans = 0;
    queue<long long> Q;
    for(int i=0;i<2*n;i++)
    {
        long long p = c[a[i%n]];
        if(p==-1)while(!Q.empty())Q.pop();
        else{
            if(Q.size()&&p<=Q.back())
                p+=(Q.back()-p+m)/m*m;
            Q.push(p);
            while(p-Q.front()>=m)
                Q.pop();
        }
        ans=max(ans,(int)Q.size());
    }
    printf("%d\n",ans);
}

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <cstring>
#include <cmath>

#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>

#define ABS(a) ((a)<0?-(a):(a))
#define SIGN(a) ((a)<0?-1:((a)>0?1:0))
#define SQR(a) ((a)*(a))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))

#define REP(i, n) for(int i=0; i<(n); ++i)
#define FOR(i, a, b) for(int i=(a); i<(b); ++i)

#define in ({int x;scanf("%d", &x);x;})

#define PI   (3.1415926)
#define INF  (2147483647)
#define INF2 (1073741823)
#define EPS  (0.000001)
#define y1 stupid_cmath

#define N 1005000

typedef long long LL;

using namespace std;

int main(){
//	freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);
	int l1, l2;
	scanf("%d%d", &l1, &l2);
	int m1[2*N], m2[N], i, j, m[N], k, f, t, ts;
	memset(m,-1,sizeof(m));
	for(i=0;i<l1;++i){
	    scanf("%d", &m1[i]);
	    m1[l1+i]=m1[i];
	}
	l1*=2;
	for(i=0;i<l2;++i){
	    scanf("%d", &m2[i]);
	    m[m2[i]]=i;
	}
	j=-1;
	int res=0;
	for(i=0;i<l1;++i){
        if(m[m1[i]]<0){
            j=-1;
            continue ;
        }
        ts=m[m1[i]];
        if(j<0){
            k=1; f=0; j=ts;
            while(i+k<l1 && m[m1[i+k]]>=0){
                t=m[m1[i+k]];
                if(t>=ts && t<=j) break;
                if(f==1 && t>=ts) break;
                if(f==1 && t<=j) break;
                if(t<=j) f=1;
                j=t;
                ++k;
            }
            res=MAX(res,k);
            if(i+k>=l1 || m[m1[i+k]]<0){
                i+=k-1;
                continue ;
            }
        }else{
            t=m[m1[i-1]];
            --k;
            if(ts<t) f=0;

            while(i+k<l1 && m[m1[i+k]]>=0){
                t=m[m1[i+k]];
                if(t>=ts && t<=j) break;
                if(f==1 && t>=ts) break;
                if(f==1 && t<=j) break;
                if(t<=j) f=1;
                j=t;
                ++k;
            }
            res=MAX(res,k);
            if(i+k>=l1 || m[m1[i+k]]<0){
                i+=k-1;
                continue ;
            }

        }
	}
	cout<<res;
	return 0;
}

#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<string>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cassert>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>

using namespace std;

#define s(n)					scanf("%d",&n)
#define sl(n) 					scanf("%lld",&n)
#define sf(n) 					scanf("%lf",&n)
#define ss(n) 					scanf("%s",n)
#define INF						(int)1e9
#define LINF					(long long)1e18
#define EPS						1e-9
#define maX(a,b)				((a)>(b)?(a):(b))
#define miN(a,b)				((a)<(b)?(a):(b))
#define abS(x)					((x)<0?-(x):(x))
#define FOR(i,a,b)				for(int i=a;i<b;i++)
#define REP(i,n)				FOR(i,0,n)
#define foreach(v,c)            for( typeof((c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define mp						make_pair
#define FF						first
#define SS						second
#define tri(a,b,c)				mp(a,mp(b,c))
#define XX						first
#define YY						second.first
#define ZZ						second.second
#define pb						push_back
#define fill(a,v) 				memset(a,v,sizeof a)
#define all(x)					x.begin(),x.end()
#define SZ(v)					((int)(v.size()))
#define DREP(a)					sort(all(a)); a.erase(unique(all(a)),a.end())
#define INDEX(arr,ind)			(lower_bound(all(arr),ind)-arr.begin())
#define debug(args...)			{dbg,args; cerr<<endl;}
#define dline					cerr<<endl

void sc(char &c){
	char temp[4];	ss(temp);
	c=temp[0];
}

struct debugger
{
	template<typename T> debugger& operator , (const T& v)
	{
		cerr<<v<<" ";
		return *this;
	}
} dbg;

void debugarr(int * arr,int n)
{
	cout<<"[";
	for(int i=0;i<n;i++)
		cout<<arr[i]<<" ";
	cout<<"]"<<endl;
}

//FastIO begin
#define BUFFERSIZE 15000000
char *ipos, *opos, InpFile[BUFFERSIZE], OutFile[10], DIP[20];
char * inputEnd;

inline bool eof()
{
	while( ipos < inputEnd && *ipos <= 32) ipos++;
	return ipos >= inputEnd;
}
inline char nc() {
	while(*ipos <= 32) ++ipos;
	return *ipos++;
}
inline int ni(int flag=0) {
	while(*ipos <= 32) ++ipos;
	if(flag) return (*ipos++ - '0'); /* For getting single digit/binary digit */
	int x=0, neg = 0;char c;
	while( true ) {
		c=*ipos++; if(c == '-') neg = 1;
		else {
			if (c<=32) return neg?-x:x;
			x=(x<<1)+(x<<3)+c-'0';
		}
	}
}
inline long long nll() {
	while(*ipos <= 32) ++ipos;
	long long x=0, neg = 0;char c;
	while( true ) {
		c=*ipos++; if(c == '-') neg = 1;
		else {
			if (c<=32) return neg?-x:x;
			x=(x<<1)+(x<<3)+c-'0';
		}
	}
}
inline void pi(int x,int flag = 1) {
	int y,dig=0;
	if(x<0) { *opos++ = '-';  x=-x;};
	while (x||!dig) { y=x/10;DIP[dig++]=x-((y << 3) + (y << 1))+'0';x=y;}
	while (dig--) *opos++=DIP[dig];
	*opos++= flag ? '\n' : ' ';
}
inline void pll(long long x,int flag = 1) {
    long long y,dig=0;
    if(x<0) { *opos++ = '-';  x=-x;};
    while (x||!dig) { y=x/10;DIP[dig++]=x-((y << 3) + (y << 1))+'0';x=y;}
    while (dig--) *opos++=DIP[dig];
    *opos++= flag ? '\n' : ' ';
}
inline void ps(string str,int flag = 1) {
	int len=str.length();
	for(int i=0;i<len;i++)	*opos++=str[i];
	*opos++= flag ? '\n' : ' ';
}
inline void pws(int flag = 1) {
	*opos++= flag ? '\n' : ' ';
}
inline void InitFASTIO() {
	ipos = InpFile; opos = OutFile;
	inputEnd = InpFile + fread(InpFile,1,BUFFERSIZE,stdin);
}
inline void FlushFASTIO() {
	fwrite(OutFile,opos-OutFile,1,stdout);
}
//FastIO end

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef pair<int,PII> TRI;

typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VII;
typedef vector<PLL> VLL;
typedef vector<TRI> VT;

typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VII> VVII;
typedef vector<VLL> VVLL;
typedef vector<VT> VVT;

/*Main code begins now */

int testnum;
int A,B;
int a[2000005];
int b[1000005];
int pos[1000005];
LL stk[2000005];
int beg,end;

void preprocess()
{

}

void solve()
{
	int ans=0;
	beg=0;
	end=0;
	int cnt1=0,cnt2=0;
	for(int i=0;i<A+A;i++)
	{
		assert(cnt2<3000000);
		assert(end< 2000005);
		int z=a[i];
		int p=pos[z];
		if(p<0)
		{
			beg=0;
			end=0;
		}
		else
		{
			LL last=(end>0) ? stk[end-1] : -1;
			LL p1 = (last/B)*B + p;
			while(p1>last)
			{
				p1-=B;
				cnt1++;
			}
			while(p1<=last)
			{
				p1+=B;
				cnt1++;
			}

			stk[end++]=p1;
			while(beg<end && stk[end-1]-stk[beg] >= B)
			{
				beg++;
				cnt2++;
			}
			if(beg==end)
			{
				beg=0;
				end=0;
			}
			ans=max(ans,end-beg);
		}
	}
	printf("%d\n",ans);

}

bool input()
{
	A=ni(); B=ni();
	for(int i=0;i<A;i++)
	{
		a[i]=ni();
		a[A+i]=a[i];
	}
	fill(pos,-1);
	for(int i=0;i<B;i++)
	{
		b[i]=ni();
		pos[b[i]]=i;
	}
	return true;
}

int main()
{
	InitFASTIO();
	preprocess();
	int T=1;
	for(testnum=1;testnum<=T;testnum++)
	{
		if(!input()) break;
		solve();
	}
}

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <cstring>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <complex>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <queue>
#include <iterator>

typedef long long LL;
typedef long double LD;

using namespace std;

const int MAX_N = 2 * 1000010;

int n, m;
int a [MAX_N], b [MAX_N], pos [MAX_N];

int brute() {
    int ret = 0;
    for (int i = 0; i < 2 * n; i++)
        for (int j = i; j < i + n; j++) {
            int cur = i;
            for (int k = 0; cur <= j && k < m; k++)
                if (b[pos[a[i]] + k] == a[cur])
                    cur++;
            if (cur > j)
                ret = max(ret, j - i + 1);
        }
    return ret;
}

int main() {
#ifndef LOCAL
//  freopen(".in", "r", stdin);
//  freopen(".out", "w", stdout);
#endif

    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        a[n + i] = a[i];
    }
    memset(pos, -1, sizeof(pos));
    for (int i = 0; i < m; i++) {
        scanf("%d", &b[i]);
        b[m + i] = b[i];
        pos[b[i]] = i;
    }

    int ans = 0;
    int i2 = 0;
    LL j1 = -m, j2 = -m;
    for (int i1 = 0; i1 < n; i1++) {
        i2 = max(i1, i2);
        while (i2 < i1 + n && i2 < 2 * n) {
            LL x = pos[a[i2]];
            if (x == -1)
                break;
            if (x < j2)
                x += m * ((j2 - x + m - 1) / m);
            if (j1 >= 0 && x - j1 >= m)
                break;

            i2++;
            if (j1 < 0)
                j1 = x;
            j2 = x;
#ifdef DEBUG
        cerr << "WHILE " << "i1 " << i1 << " i2 " << i2 << " j1 " << j1 << " j2 " << j2 << '\n';
#endif
        }

#ifdef DEBUG
        cerr << "i1 " << i1 << " i2 " << i2 << " j1 " << j1 << " j2 " << j2 << '\n';
#endif

        ans = max(ans, i2 - i1);

        if (i1 + 1 < i2) {
            LL x = pos[a[i1 + 1]];
            assert(x >= 0);
            if (x < j1)
                x += m * ((j1 - x + m - 1) / m);
            j1 = x;
        }
        else
            j1 = j2 = -m;
    }

#ifdef LOCAL
    int br = brute();
    if (ans != br) {
        cerr << "ans " << ans << " br " << br << '\n';
        cerr << "FUCK\n";
        assert(0);
    }
#endif
    cout << ans << '\n';
    return 0;
}

#include <cstdio>
#include <algorithm>
using namespace std;

const int Maxn = 2000005;
const int Inf = 1000000000;

int la, lb;
int a[Maxn];
int b[Maxn];
int pos[Maxn];
int tpos[Maxn];
int res;

int getNxt(int val, int p)
{
	if (pos[val] >= p) return pos[val];
	if (pos[val] + lb >= p) return pos[val] + lb;
	return Maxn;
}

int main()
{
	scanf("%d %d", &la, &lb);
	for (int i = 0; i < la; i++) {
		scanf("%d", &a[i]); a[la + i] = a[i];
	}
	fill(pos, pos + Maxn, Inf);
	for (int i = 0; i < lb; i++) {
		scanf("%d", &b[i]); b[lb + i] = b[i];
		pos[b[i]] = i;
	}
	fill(tpos, tpos + 2 * la, Inf);
	int j = -1;
	for (int i = 0; i < 2 * la; i++) if (getNxt(a[i], -1) < Inf) {
		tpos[i] = getNxt(a[i], -1);
		for (int k = i + 1; k < 2 * la; k++)
			if (getNxt(a[k], tpos[k - 1] + 1) < tpos[k])
				tpos[k] = getNxt(a[k], tpos[k - 1] + 1);
			else break;
		if (j < i) j = i;
		while (j < 2 * la && j - i + 1 <= la && tpos[j] - tpos[i] + 1 <= lb) j++;
		res = max(res, j - i);
	}
	printf("%d\n", res);
	return 0;
}

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <bitset>       //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <iomanip>      //do setprecision
#include <ctime>
#include <complex>
using namespace std;

#define FOR(i,b,e) for(int i=(b);i<(e);++i)
#define FORQ(i,b,e) for(int i=(b);i<=(e);++i)
#define FORD(i,b,e) for(int i=(b)-1;i>=(e);--i)
#define REP(x, n) for(int x = 0; x < (n); ++x)

#define ST first
#define ND second
#define PB push_back
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double

const double pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;

#define MR 1000010

int a[MR], b[MR], wa[MR], wb[MR];   //hieroglify i wystapienia hieroglifow

int main()
{
    memset(wa,-1,sizeof(wa));
    memset(wb,-1,sizeof(wb));
    int la, lb;
    scanf("%d%d", &la, &lb);
    REP(i,la)
    {
        scanf("%d", &a[i]);
        wa[a[i]] = i;
    }
    REP(i,lb)
    {
        scanf("%d", &b[i]);
        wb[b[i]] = i;
    }
    if(la == 1)
    {
        printf("%d\n", wb[a[0]] == -1 ? 0 : 1);
        return 0;
    }
    if(lb == 1)
    {
        printf("%d\n", wa[b[0]] == -1 ? 0 : 1);
        return 0;
    }
    int res = 0;
    int end = -1, x = wb[a[0]], y = wb[a[0]];
    bool cond = 0;
    REP(i,la)
    {
        if(wb[a[i]] == -1) break;   //nie ma hieroglifu w b
        if(wb[a[i]] < x && !cond)   //od tego momentu trzeba wprowadzic warunek
        {
            cond = 1;
            y = wb[a[i]];
            end = i;                //przesun koniec
        }
        if(!cond)
        {
            if(wb[a[i]] < y)
                break;
            y = wb[a[i]];   //indeksy dalej rosna
            end = i;
        }
        else if(cond)       //spr, czy indeks trafia tam gdzie trzeba
        {
            if(wb[a[i]] < y || wb[a[i]] > x)    //nie wystepuje jako podciag
                break;
            y = wb[a[i]];
            end = i;    //przesun koniec
        }
    }
    if(end != -1) res = end+1;
    if(res == la)
    {
        printf("%d\n", la);
        return 0;
    }
    //przesuwaj poczatek o 1 i probuj poszerzac koniec
    bool endza = 0;
    FOR(i,1,la)
    {
        if(wb[a[i]] == -1) continue;    //nie ma poczatku w b, od razu mozemy go pominac i sprawdzic nastepny
        if(!endza && end < i) end = i;
        if(wb[a[i]] < x) cond = 0;  //nie ma warunku
        x = wb[a[i]];
        while(true)
        {
            if(endza && end == i-1) break;      //mamy cale a
            if(wb[a[(end+1)%la]] == -1) break;  //nie ma kolejnego hieroglifu w b -> nie da sie poszerzyc konca
            if(wb[a[(end+1)%la]] < x && !cond)  //od tego momentu trzeba wprowadzic warunek
            {
                cond = 1;
                y = wb[a[(end+1)%la]];
                if(end == la-1) endza = 1;      //end sie przekrecil
                end = (end+1)%la;               //przesun koniec
            }
            if(!cond)
            {
                if(wb[a[(end+1)%la]] < y)
                    break;
                y = wb[a[(end+1)%la]];          //indeksy rosna dalej
                if(end == la-1) endza = 1;      //end sie przekrecil
                end = (end+1)%la;               //przesun koniec
            }
            else        //spr czy indeks trafil tam gdzie trzeba
            {
                if(wb[a[(end+1)%la]] < y || wb[a[(end+1)%la]] > x)
                    break;
                y = wb[a[(end+1)%la]];          //indeksy rosna dalej
                if(end == la-1) endza = 1;      //end sie przekrecil
                end = (end+1)%la;
            }
        }
        //spr nowa dlugosc
        if(!endza) res = max(res, end-i+1);
        else res = max(res, end+1+la-i);
    }
    printf("%d\n", res);
    return 0;
}

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <queue>
#include <math.h>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <bitset>
#include <list>
#include <ctype.h>
#include <cassert>
#include <stack>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <ctime>
#include <functional>
#include <ctime>

using namespace std;

#define snd second
#define fst first
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld double
#define pb push_back
#define left _left
#define right _right

const ld pi = 3.14159265359;

template<typename T>
T abs(T x) {
    return x > 0 ? x : -x;
}

template<typename T>
T sqr(T x) {
    return x * x;
}

template<typename T>
void chmin(T &x, T y) {
    x = min(x, y);
}

template<typename T>
void chmax(T &x, T y) {
    x = max(x, y);
}

template<typename U, typename V>
ostream &operator<<(ostream &s, const pair<U, V> &x) {
    s << "(" << x.fst << ", " << x.snd << ")";
    return s;
}

template<typename U>
ostream &operator<<(ostream &s, const vector<U> &x) {
    s << "[";
    bool was = false;
    for (auto it : x) {
        if (was) {
            s << ", ";
        }
        was = true;
        s << it;
    }
    s << "]";
    return s;
}

template<typename U>
ostream &operator<<(ostream &s, const set<U> &x) {
    s << "{";
    bool was = false;
    for (auto it : x) {
        if (was) {
            s << ", ";
        }
        was = true;
        s << it;
    }
    s << "}";
    return s;
}

template<int sz>
ostream operator << (ostream &s, const bitset<sz> &x) {
    for (int i = 0; i < sz; i++) {
        s << x[i];
    }
    return s;
}

//-----------------------------------------------------------------------------

const int maxn = 2e6 + 5;
int a[maxn], b[maxn];

int main() {
    srand(time(NULL));

    retry:

#ifdef LOCAL
    //gen();
    //cerr << 1 << endl;
    freopen("a.in", "r", stdin);
#else
    //freopen("fract.in", "r", stdin);
    //freopen("fract.out", "w", stdout);
#endif

    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
        a[n + i] = a[i];
    }

    fill(b, b + maxn, -1);

    for (int i = 0; i < m; i++) {
        int x;
        scanf("%d", &x);
        b[x] = i;
    }

    int ans = 0;
    deque<ll> q;
    ll f = 0;

    for (int i = 0; i < n + n; i++) {
        if (q.empty()) {
            if (b[a[i]] != -1) {
                q.push_front(b[a[i]] + f * m);
            }

            chmax(ans, (int)q.size());
            continue;
        } else {
            ll x = q.front();
            ll y = b[a[i]];

            if (y == -1) {
                q.clear();
                continue;
            }

            y += f * m;

            if (y <= x) {
                y += m;
                f++;
            }

            q.push_front(y);

            while (q.front() - q.back() >= m) {
                q.pop_back();
            }

            chmax(ans, (int)q.size());
        }
    }

    cout << ans << endl;

    return 0;
}

#include <cstdio>
#include <numeric>
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <queue>
#include <sstream>
#include <deque>

using namespace std;

#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0; i < (n); i++)
#define re return
#define fi first
#define se second
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(abs(x))
#define y0 y3487465
#define y1 y8687969
#define fill(x,y) memset(x,y,sizeof(x))

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef double D;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<vi> vvi;

template<class T> T abs(T x) { re x > 0 ? x : -x; }

int n;
int m;
int x[2000000], f[1000000];

int get (int a, int b) {
    if (a > b) b += m;
    re b - a;
}

int main () {
    scanf ("%d%d", &n, &m);
    for (int i = 0; i < 1000000; i++) f[i] = -1;
    for (int i = 0; i < n; i++) {
        scanf ("%d", &x[i]); x[i]--;
        x[n + i] = x[i];
    }
    for (int i = 0; i < m; i++) {
        int y;
        scanf ("%d", &y); y--;
        f[y] = i;
    }
    int l = 0, r = 0, y = -1, len = 0, cnt = 0;
    int ans = 0;
    while (r < 2 * n) {
        if (f[x[r]] == -1) {
            l = r + 1;
            y = -1;
            len = 0;
            cnt = 0;
        } else {
            if (y == -1) {
                y = f[x[r]];
                len = 0;
                cnt = 1;
            } else {
                len += get (y, f[x[r]]);
                y = f[x[r]];
                cnt++;
                while (len >= m) {
                    len -= get (f[x[l]], f[x[l + 1]]);
                    cnt--;
                    l++;
                }
            }
        }
        ans = max (ans, cnt);
        r++;
    }
    printf ("%d\n", min (ans, n));
    return 0;
}

#include <cstdio>
#include <vector>
#include <cstring>
#include <deque>
#include <algorithm>
using namespace std;

int locate(const vector<int>& u, int x){
    return lower_bound(u.begin(),u.end(),x)-u.begin();
}

int n,m,a[1000005],b[1000005];
int tag[1000005],pos[1000005];

bool seq(int i, int j, int n){
    int k=j+1;
    //printf("check for k = %d\n",k);
    if(k%n==i || tag[k%n]<0) return false;
    if(tag[i]<=tag[j%n]){
        //puts("branch 1");
        if(tag[j%n]<tag[k%n]
        || tag[k%n]<tag[i]) return true;
        //puts("failed");
        return false;
    }else{
        //puts("branch 2");
        if(tag[j%n]<tag[k%n]
        && tag[k%n]<tag[i]) return true;
        //puts("failed");
        return false;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    vector<int> u;
    for(int i=0;i<n;i++) scanf("%d",a+i);
    memset(pos,-1,sizeof(pos));
    for(int i=0;i<m;i++){
        scanf("%d",b+i);
        pos[b[i]]=i;
    }
    for(int i=0;i<n;i++){
        tag[i]=pos[a[i]];
        //printf("%d ",tag[i]);
    }
    //puts("");
    int ans=0;
    for(int i=0,j=0;i<n;i++){
        if(tag[i]<0) continue;
        //printf("i = %d, ",i);
        if(j<=i) j=i;
        //printf("j = %d\n",j);
        while(seq(i,j,n)){
            j++;
            //printf(" -> %d",j);
        }
        //puts("");
        ans=max(ans,j-i+1);
    }
    printf("%d\n",ans);
}

#pragma comment(linker, "/STACK:10000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <cassert>
#include <cstdio>
#include <iostream>
#include <sstream>
#include <numeric>
#include <bitset>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <functional>
#include <cstring>
#include <ctime>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pii;
template <class T> T inline sqr(T x) { return x * x; }
template <class T> string str( T i ) { stringstream ss; ss << i; return ss.str(); }
int toint(string a) {istringstream is(a); int p; is>>p; return p;}
long long toll(string a){istringstream is(a);long long p;is>>p;return p;}

#define pb push_back
#define mp make_pair
#define e1 first
#define e2 second
#define sz size

#if ( _WIN32 || __WIN32__ )
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif
#define forn(i, n) for (i = 0; i < int(n); i++)
#define setval(a,v) memset(a, v, sizeof(a))
const ld pi = 3.1415926535897932384626433832795, eps = 1e-8;

const int maxn = 1000500;
int a[maxn], b[maxn];
pii g[maxn];
int pos[maxn * 2];
int w[maxn];
int c[maxn];

int main()
{
   //freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
   int i, n, m, x;
	scanf("%d%d", &n, &m);
	forn (i, n)
		scanf("%d", &a[i]);
	forn (i, m)
	{
		scanf("%d", &b[i]);
		g[i].e1 = b[i];
		g[i].e2 = i;
		w[b[i]] = i + 1;
	}
	forn (i, n)
	{
		if (w[a[i]] != 0)
			pos[i] = w[a[i]] - 1;
		else
			pos[i] = -1;
		pos[i + n] = pos[i];
	}

	int ans = 0;
	int curlen = 0, j;

	for (i = 0; i < n; i++)
	{
		if (pos[i] == -1)
		{
			curlen = 0;
			continue;
		}

		if (curlen <= 1)
		{
			j = i + 1;
			curlen = 1;
			while (curlen < n)
			{
				if (pos[j] == -1)
					break;
				if (pos[j] > pos[i])
				{
					if (pos[j] < pos[j - 1] || pos[j - 1] < pos[i])
						break;
				}
				else
				{
					if (pos[j - 1] < pos[i] && pos[j - 1] > pos[j])
						break;
				}

				j++;
				curlen++;
			}
			ans = max(ans, curlen);
		}
		else
		{
			curlen--;
			j = i + curlen;
			while (curlen < n)
			{
				if (pos[j] == -1)
					break;
				if (pos[j] > pos[i])
				{
					if (pos[j] < pos[j - 1] || pos[j - 1] < pos[i])
						break;
				}
				else
				{
					if (pos[j - 1] < pos[i] && pos[j - 1] > pos[j])
						break;
				}

				j++;
				curlen++;
			}
			ans = max(ans, curlen);
		}

	}
	cout << ans;
	return 0;
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#pragma warning( disable : 4244 4267 4018 4996 4800 )
//#pragma comment( linker, "/stack:10000000" )
using namespace std;
typedef vector< int > vi; typedef vector< vector< int > > vvi; typedef vector< string > vs; typedef vector< double > vd;
typedef vector< vd > vvd; typedef long long ll; typedef vector< ll > vll; typedef vector< vll > vvll; typedef pair< int, int > pii;
#define all( v ) (v).begin( ), (v).end( )

#ifdef LOCAL
ifstream in( "b.in" );
#else
istream & in = cin;
#endif
ostream & out = cout;

int main() {
#ifdef LOCAL
    freopen("b.in", "r", stdin);
#endif
    int na, nb;
    scanf("%d %d", &na, &nb);
    vi a(na), b(nb);
    vi pos(1e6+1, -1);
    for (int i = 0; i < na; ++i) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < nb; ++i) {
        scanf("%d", &b[i]);
        pos[b[i]] = i;
    }

    int res = 0;
    for (int l = 0, r = 0; l < na; ++l) {
        if (pos[a[l]] == -1) {
            r = l + 1;
            continue;
        }
        int curpos = pos[a[r]];
        for (;;) {
            int t = (r + 1) % na;
            if (t == l) break;
            int nextpos = pos[a[t]];
            if (nextpos == -1) break;
            if (curpos >= pos[a[l]] && nextpos <= curpos && nextpos >= pos[a[l]])
                break;
            if (curpos < pos[a[l]] && (nextpos <= curpos || nextpos >= pos[a[l]]))
                break;
            r = t;
            curpos = nextpos;
        }
        if (r >= l)
            res = max(res, r - l + 1);
        else
            res = max(res, r + na - l + 1);
    }
    out << res;
    return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int p[1000010],a[1000010],n,m,ans;
deque<int>q;
bool in(int x,int L,int R){
    if(L<=R)return L<=x&&x<=R;
    else return x<=R||L<=x;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)scanf("%d",&a[i]);
    memset(p,-1,sizeof p);
    for(int i=0,x;i<m;++i){
        scanf("%d",&x);
        p[x]=i;
    }
    for(int i=0;i<n+n;++i){
        if(p[a[i%n]]==-1){
            q.clear();
            continue;
        }
        while(!q.empty()&&in(p[a[i%n]],q.front(),q.back()))q.pop_front();
        q.push_back(p[a[i%n]]);
        ans=max(ans,(int)q.size());
        if(ans>=min(m,n))
            break;
    }
    printf("%d\n",ans);
    return 0;
}

/* Writen by Filip Hlasek 2012 */
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstring>

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,b) for(int i=0;i<b;i++)

using namespace std;

#define MAXN 1111111
int a[2*MAXN],b[MAXN],A,B;
int pos[MAXN];

int main(int argc, char *argv[]){
  REP(i,MAXN) pos[i] = -1;
  scanf("%d%d",&A,&B);
  REP(i,A){
    scanf("%d",a+i);
    a[A+i] = a[i];
  }
  REP(i,B) scanf("%d",b+i);
  REP(i,B) pos[b[i]] = i;
  int start = 0, end = 0, best = 0;
  while(start < A && pos[a[start]] == -1) start++;
  if(start == A){ printf("0\n"); return 0; }
  end = start;
  bool over = false;
  while(start < A){
    //printf("start:%d end:%d over:%d - next:%d pos-start:%d\n",start,end,(int)over,pos[a[end+1]],pos[start]);
    while(pos[a[end+1]] != -1 && ((!over && (pos[a[end+1]] > pos[a[end]] || pos[a[end+1]] < pos[a[start]])) ||
                                            (pos[a[end+1]] > pos[a[end]] && pos[a[end+1]] < pos[a[start]]))){
      if(pos[a[end+1]] <= pos[a[end]]) over = true;
      end++;
    }
    //printf("...start:%d end:%d over:%d\n",start,end,(int)over);
    best = max(best, end - start + 1);
    start++;
    if(end < start){
      over = false;
      while(start < A && pos[a[start]] == -1) start++;
      end = start;
    }
    else if(pos[a[start]] < pos[a[start-1]]) over = false;
  }
  printf("%d\n",best);
  return 0;
}

#pragma comment(linker, "/STACK:100000000")
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <ctime>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
#define int64 long long
#define ldb long double
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define sz(a) ((int) (a).size())
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define taskname "task_b"
const ldb pi = acos(-1.0);
const int N = (int) 2e6 + 10;
int a[N], x, pos[N], n, m, ans;

int main() {
//	assert(freopen(taskname".in", "r", stdin));
//	assert(freopen(taskname".out", "w", stdout));
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i)
		scanf("%d", &a[i]), --a[i];
	memset(pos, -1, sizeof(pos));
	for (int i = 0; i < m; ++i)
		scanf("%d", &x), --x, pos[x] = i;
	for (int i = 0; i < n; ++i) {
		a[i] = pos[a[i]];
		a[i + n] = a[i];
	}
	bool was_down = false;
	for (int i = 0, j = 0; i < 2 * n; ++i) {
		if (a[i] == -1) {
			j = i + 1;
			was_down = false;
			continue;
		}
		if ((i > 0) && (a[i - 1] > a[i])) {
			while ((j < i) && ((i - j + 1 > n) || was_down || (a[j] <= a[i]))) {
				if (a[j] > a[j + 1]) was_down = false;
				++j;
			}
		} else {
			while ((j < i) && ((i - j + 1 > n) || (was_down && (a[j] <= a[i])))) {
				if (a[j] > a[j + 1]) was_down = false;
				++j;
			}
		}
		if ((i > 0) && (a[i - 1] > a[i])) was_down = true;
		ans = max(ans, i - j + 1);
		// eprintf("j = %d, was_down = %d, ans = %d\n", j, (int) was_down, ans);
	}
	printf("%d\n", ans);
	return 0;
}

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

#define fore(i, a, b) for (int i = int(a); i < int(b); i++)
#define forn(i, n) fore(i, 0, n)
#define efor(i, a, b) for (int i = int(b) - 1; i >= int(a); i--)
#define nfor(i, n) efor(i, 0, n)

#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define all(v) (v).begin(), (v).end()
#define sz(v) int((v).size())
#define x first
#define y second

template <typename T> T abs(const T& x) { return x < 0 ? -x : x; }
template <typename T> T sqr(const T& x) { return x * x; }

template<typename X, typename Y> ostream& operator<< (ostream& out, const pair<X, Y>& p) {
	return out << "(" << p.x << ", " << p.y << ")";
}

template<typename X> ostream& operator<< (ostream& out, const vector<X>& a) {
	out << "[ ";
	forn(i, sz(a)) {
		if (i) out << ", ";
		out << a[i];
	}
	return out << " ]";
}

typedef long long li;
typedef long double ld;
typedef pair<int,int> pt;

ld gett() {
	return clock() / ld(CLOCKS_PER_SEC);
}

#ifdef TJS

#endif

const int N = 2 * 1000 * 1000 + 5;
int n, m;
int a[N], b[N];

bool read() {
/*	n = int(1e6);
	m = n;
	forn(i, n)
		a[i] = b[i] = i + 1;
	random_shuffle(a, a + n);
	random_shuffle(b, b + m);
	return true;*/

	if (!(cin >> n >> m))
		return false;
	forn(i, n)
		assert(scanf("%d", &a[i]) == 1);
	forn(i, m)
		assert(scanf("%d", &b[i]) == 1);

	return true;
}

int posb[N];

inline int getpos(int v) {
	return posb[v];
}

inline li move(li from, li to) {
	to += (from / m) * m;
	int T = 0;
	while (to < from) {
		to += m;
		T++;
	}
	assert(T <= 2);
	return to;
}

void solve() {
	memset(posb, -1, sizeof(posb));
	forn(i, m) {
		posb[b[i]] = i;
	}

	int r = 0;
	li lf = 0, rg = 0;
	int res = 0;
	for (int l = 0; l < n; ++l) {
		int p = getpos(a[l]);

		if (p == -1) {
			lf = 0, rg = 0;
			continue;
		}

		if (lf == rg) {
			lf = p;
			rg = p + 1;
			r = l + 1;
		}

		while (true) {
			if (r + 1 - l > n)
				break;

			li pnr = getpos(a[r % n]);

			if (pnr == -1)
				break;

			li nrg = move(rg, pnr) + 1;

			if (nrg - lf > m)
				break;

			rg = nrg;
			r++;
		}

		res = max(res, r - l);

		if (l + 1 == r) {
			lf = rg = 0;
		} else {
			li pl1 = getpos(a[(l + 1) % n]);
			assert(pl1 != -1);
			lf = move(lf, pl1);
		}
	}

	cout << res << endl;
}

int main() {
#ifdef TJS
	assert(freopen("input.txt", "r", stdin));
#else
#endif
	cerr << fixed << setprecision(5);
	cout << fixed << setprecision(10);
	while (read()) {
#ifdef TJS
		ld st = gett();
#endif
		solve();
#ifdef TJS
		cerr << " == TIME : " << gett() - st << " == " << endl;
#endif
			break;
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define null NULL
#define mp make_pair
#define pb(a) push_back(a)
#define sz(a) ((int)(a).size())
#define all(a) a.begin() , a.end()
#define fi first
#define se second
#define relaxMin(a , b) (a) = min((a),(b))
#define relaxMax(a , b) (a) = max((a),(b))
#define SQR(a) ((a)*(a))
#define PI 3.14159265358979323846
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

int la, lb;
deque<int> a, b;
int pos[(int)1E6 + 10];

bool OK(deque<int>& on, int pos){
  if(on.empty()) return true;

  if(on.front() <= on.back()){
    if(on.back() < pos) return true;
    if(pos < on.front()) return true;
  }

  if(on.front() > on.back() &&
     on.back() < pos &&
     pos < on.front()) return true;

  return false;
}

int main(){
  scanf("%d%d", &la, &lb);
  a.resize(la), b.resize(lb);
  for(int& _a : a) scanf("%d", &_a);
  for(int& _b : b) scanf("%d", &_b);

  memset(pos, -1, sizeof pos);
  for(int i = 0;i < lb;++i) pos[b[i]] = i;

  int ml = 0;
  deque<int> same;

  for(int s = 0;s < la;++s){
    if(!same.empty()) same.pop_front();

    while(sz(same) < la){
      int len = sz(same);
      if(pos[a[len]] == -1) break;
      int y = pos[a[len]];
      if(!OK(same, y)) break;
      same.pb(y);
    }

    relaxMax(ml, sz(same));
    a.pb(a[0]), a.pop_front();
  }

  printf("%d\n", ml);
  return 0;
}

//#define BITSET64BIT 1
#ifdef BITSET64BIT
#include <string>
#include <bits/functexcept.h>
#include <iosfwd>
#include <bits/cxxabi_forced.h>
#include <bits/functional_hash.h>

#pragma push_macro("__SIZEOF_LONG__")
#pragma push_macro("__cplusplus")
#define __SIZEOF_LONG__ __SIZEOF_LONG_LONG__
#define unsigned unsigned long
#define __cplusplus 201102L

#define __builtin_popcountl __builtin_popcountll
#define __builtin_ctzl __builtin_ctzll

#include <bitset>

#pragma pop_macro("__cplusplus")
#pragma pop_macro("__SIZEOF_LONG__")
#undef unsigned
#undef __builtin_popcountl
#undef __builtin_ctzl
#endif

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

// Optimization

/*
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma comment(linker,"/stack:200000000")
*/
#define endl '\n'

// Shortcut

#define int long long
#define eb emplace_back
#define pb push_back
#define pob pop_back
#define upb upper_bound
#define lwb lower_bound
#define fi first
#define se second
#define For(i, l, r) for (int i = l; i < r; i++)
#define ForE(i, l, r) for (int i = l; i <= r; i++)
#define Ford(i, r, l) for (int i = r; i > l; i--)
#define FordE(i, r, l) for (int i = r; i >= l; i--)
#define Fora(i, a) for (auto i : a)

// I/O & Debug

#define PrintV(a) Fora(h13, a) cout << h13 << ' '; cout << endl;
#define PrintVl(a) Fora(h13, a) cout << h13 << endl;
#define PrintA(a, l, r) for (int h13 = l; h13 <= r; h13++) cout << a[h13] << ' '; cout << endl;
#define PrintAl(a, l, r) for (int h13 = l; h13 <= r; h13++) cout << a[h13] << endl;
#define Ptest(x) return cout << x, 0;
#define getl(s) getline(cin, s);
#define setpre(x) fixed << setprecision(x)
/*
#define debug(args...){                                                                     \\
    string _sDEB = #args;                                                                   \\
    replace(_sDEB.begin(), _sDEB.end(), ',', ' ');                                          \\
    stringstream _ssDEB(_sDEB);                                                             \\
    istream_iterator<string> _itDEB(_ssDEB);                                                \\
    DEB(_itDEB, args);                                                                      \\
}
void DEB(istream_iterator<string> it) {}
template<typename T, typename... Args>
void DEB(istream_iterator<string> it, T a, Args... args){
    cout << *it << " = " << a << endl;
    DEB(++it, args...);
}
*/

// Functions

//#define isvowel(a) (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
#define bend(a) a.begin(), a.end()
#define rbend(a) a.rbegin(), a.rend()
#define mset(a) memset(a, 0, sizeof(a))
#define mset1(a) memset(a, 1, sizeof(a))
#define msetn1(a) memset(a, -1, sizeof(a))
#define msetinf(a) memset(a, 0x3f, sizeof(a))
#define gcd __gcd
#define __builtin_popcount __builtin_popcountll
//mt19937 rando(chrono::steady_clock::now().time_since_epoch().count());
//int randt(int l, int r){ return (rando() % (r - l + 1) + l); }

// Data Structure

// Policy based data structures                                                             \\
   Support find_by_order(int k): return an iterator to the k-th smallest element,           \\
                                 counting from 0                                            \\
           order_of_key(int k): return the number of items strictly smaller than k          \\
   For ordered_multiset and ordered_multimap, lower_bound() and upper_bound() are swapped

template <typename T> using ordered_set =
tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename Key, typename T> using ordered_map =
tree <Key, T, less <Key>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =
tree <T, null_type, less_equal <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename Key, typename T> using ordered_multimap =
tree <Key, T, less_equal <Key>, rb_tree_tag, tree_order_statistics_node_update>;

#define y0 _y0_
#define y1 _y1_
#define div divi
typedef long long ll;
typedef long double ld;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <ld> vld;
typedef vector <string> vs;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <vi > vvi;
typedef vector <vll > vvll;
typedef vector <pii > vpii;
typedef vector <pll > vpll;

const int N = 2e6 + 5;
int mod = 1e9 + 7, mod1 = 998244353, mod2 = 1e9 + 9, inf = 1e9 + 7;
ll infll = 1e18 + 7;

int la, lb;
int a[N], b[N];

bool ck(int x, int y, int z){
    // cout << x << ' ' << y << ' ' << z << endl;
    if (!z) return 0;
    if (x > y) y += lb;
    if (y > z) z += lb;
    return (y <= z && z - x < lb);
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> la >> lb;
    ForE(i, 1, la){
        cin >> a[i];
        a[la + i] = a[i];
    }
    ForE(i, 1, lb){
        int x; cin >> x;
        b[x] = i;
    }
    int i = 1, j = 1, ans = 0;
    while (i <= la){
        if (!b[a[i]]){
            i++;
            continue;
        }
        j = max(j, i);
        while (j - i + 1 < la && ck(b[a[i]], b[a[j]], b[a[j + 1]])) j++;
        ans = max(ans, j - i + 1);
        i++;
    }
    cout << ans;
}

/*
==================================+
INPUT:                            |
------------------------------    |

------------------------------    |
==================================+
OUTPUT:                           |
------------------------------    |

------------------------------    |
==================================+
*/

#include <cstdio>
#include <cstring>

#include <vector>
#include <algorithm>

using namespace std;

typedef vector<int> VI;

#define SZ(a) int((a).size())

#define REP(i,n) for(int i=0,_n=(n);i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)

#define MAXLEN 1000004

typedef long long llong;

int lenA, lenB;
int A[MAXLEN];
int B[MAXLEN];

int idxB[1000004];

int main() {
   scanf("%d %d", &lenA, &lenB);
   REP(i, lenA)
      scanf("%d", A+i);
   memset(idxB, -1, sizeof(idxB));
   REP(j, lenB) {
      scanf("%d", B+j);
      idxB[ B[j] ] = j;
   }

   int idxV = 0;
   vector<llong> V;
   llong offset = 0;
   int res = 0;
   REP(k, lenA*2) {
      llong p = idxB[ A[ k % lenA ] ];
      if (p < 0) {
         V.clear();
         idxV = 0;
         continue;
      }
      p += offset;
      if (!V.empty() && V.back() >= p) {
         p += lenB;
         offset += lenB;
      }
      V.push_back(p);
      idxV = (lower_bound(V.begin()+idxV, V.end(), p-lenB+1) - V.begin());
      int len = SZ(V) - idxV;
      res = max(res, len);
   }
   printf("%d\n", res);

   return 0;
}

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <bitset>
#include <complex>

using namespace std;

typedef unsigned uint;
typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

const int INF = 1001001001;
#define MAX 1000010

int M, N;
int A[MAX], B[MAX];
int invB[MAX];

Int D[MAX * 2];
Int DSum[MAX * 2];

int main() {
	int i, j, x;

	for (; ~scanf("%d%d", &M, &N); ) {
		for (i = 0; i < M; ++i) {
			A[i] = in();
		}
		for (x = 0; x < N; ++x) {
			B[x] = in();
		}
		memset(invB, ~0, sizeof(invB));
		for (x = 0; x < N; ++x) {
			invB[B[x]] = x;
		}
		for (i = 0; i < M * 2; ++i) {
			int x0 = invB[A[ i      % M]];
			int x1 = invB[A[(i + 1) % M]];
			if (~x0 && ~x1) {
				for (D[i] = x1 - x0; D[i] <= 0; D[i] += N);
			} else {
				D[i] = INF;
			}
		}
// cout<<"D : ";pv(D,D+M*2);
		for (i = 0; i < M * 2; ++i) {
			DSum[i + 1] = DSum[i] + D[i];
		}
		int ans = 0;
		for (j = 0, i = 0; i < M; ++i) {
			for (; j <= i + M && DSum[j] - DSum[i] < N; ++j);
// cout<<"i = "<<i<<", j = "<<j<<endl;
			if (~invB[A[i % M]]) {
				chmax(ans, j - i);
			}
		}
		printf("%d\n", ans);
	}

	return 0;
}

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;

#define lowbit(x) ((x)&(-(x)))
#define sqr(x) ((x)*(x))
#define PB push_back
#define MP make_pair

typedef unsigned long long ULL;
typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int,int> PII;

struct Tpoint
{
    double x,y;
    Tpoint(){}
    Tpoint(double _x,double _y){x=_x;y=_y;}
    inline void read(){scanf("%lf%lf",&x,&y);}
    inline void show(){printf("%lf %lf\n",x,y);}
    inline double norm(){ return sqrt( sqr(x)+sqr(y) ); }
};

inline Tpoint operator +(const Tpoint &a,const Tpoint &b){ return Tpoint(a.x+b.x,a.y+b.y); }
inline Tpoint operator -(const Tpoint &a,const Tpoint &b){ return Tpoint(a.x-b.x,a.y-b.y); }
inline Tpoint operator *(const Tpoint &a,const double &b){ return Tpoint(a.x*b,a.y*b); }
inline Tpoint operator /(const Tpoint &a,const double &b){ return Tpoint(a.x/b,a.y/b); }
inline double det(const Tpoint &a,const Tpoint &b){ return a.x*b.y-a.y*b.x; }
inline double dot(const Tpoint &a,const Tpoint &b){ return a.x*b.x+a.y*b.y; }
//=============================================================================================

const int maxn  =   2000005;

deque<long long> q;
int la,lb,a[maxn],b[maxn],pos[maxn];

int main()
{
    scanf("%d%d",&la,&lb);
    for (int i=0;i<la;++i){
        scanf("%d",&a[i]);
        a[i+la]=a[i];
    }

    memset(pos,-1,sizeof(pos));
    for (int i=0;i<lb;++i){
        scanf("%d",&b[i]);
        pos[b[i]]=i;
    }

    q.clear();
    int ans=0;
    for (int i=0,j=0;i<la;++i){
        if (j<i){
            j=i;
            q.clear();
        }
        while (j<i+la){
            if (pos[a[j]]==-1) break;

            long long p=pos[a[j]];
            if (q.size()){
                p+=lb*(q.front()/lb);
                if (p<q.front()) p+=lb;
            }
            if (q.empty() || q.back()<p){
                q.push_back(p);
            }else break;
            ++j;
        }

        //printf("%d %d\n",i,j);

        ans=max(ans,(int)q.size());

        if (q.size()){
            q.pop_front();
        }
    }

    printf("%d\n",ans);

    return 0;
}

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
const int maxN = 1e6 + 10;
const int LOG = 22;
int nxt[maxN][LOG];
int la, lb;
int posB[maxN];
int val[maxN];
const int INF = 1e9;
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("input.txt", "r", stdin);
    cin >> la >> lb;
    for (int i = 0; i < la; i++) {
        cin >> val[i];
    }
    memset(posB, -1, sizeof posB);
    for (int i = 0; i < lb; i++) {
        int y;
        cin >> y;
        posB[y] = i;
    }
    for (int i = 0; i < la; i++) {
        if (posB[val[i]] == -1 || posB[val[(i + 1) % la]] == -1) {
            nxt[i][0] = INF;
        }
        else {
            if (posB[val[i]] < posB[val[(i + 1) % la]]) {
                nxt[i][0] = posB[val[(i + 1) % la]] - posB[val[i]];
            }
            else {
                nxt[i][0] = lb + posB[val[(i + 1) % la]] - posB[val[i]];
            }
        }
    }
    for (int c = 1; c <= 20; c++) {
        for (int i = 0; i < la; i++) {
            nxt[i][c] = min(INF, nxt[i][c - 1] + nxt[(i + (1 << (c - 1))) % la][c - 1]);
        }
    }
    int best = 0;
    for (int i = 0; i < la; i++) {
        if (posB[val[i]] == -1) continue;
        int lft = lb - 1;
        int ans = 1;
        int ci = i;
        for (int k = 20; k >= 0; k--) {
            if (nxt[ci][k] <= lft) {
                ans += (1 << k);
                lft -= nxt[ci][k];
                ci = (ci + (1 << k)) % la;
            }
        }
        best = max(best, min(ans, la));
    }
    cout << best;
    return 0;
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#pragma warning( disable : 4244 4267 4018 4996 4800 )
//#pragma comment( linker, "/stack:10000000" )
using namespace std;
typedef vector< int > vi; typedef vector< vector< int > > vvi; typedef vector< string > vs; typedef vector< double > vd;
typedef vector< vd > vvd; typedef long long ll; typedef vector< ll > vll; typedef vector< vll > vvll; typedef pair< int, int > pii;
#define all( v ) (v).begin( ), (v).end( )

#ifdef LOCAL
ifstream in( "b.in" );
#else
istream & in = cin;
#endif
ostream & out = cout;

int main() {
    //std::ofstream f("b.in");
    //f << 1000000 << ' ' << 1000000 << '\n';
    //for (int i = 0; i < 2; ++i) {
    //    for (int j = 1; j <= 1e6; ++j) f << j << ' ';
    //    f << '\n';
    //}
    //return 0;
    //int na, nb;
    //stringstream ss; ss << in.rdbuf();
    //string s = ss.str();
    ////const char * ptr = s.c_str();
    ////ptr += sscanf(ptr, "%d %d", &na, &nb);
    ////istringstream
    //in >> na >> nb;
    ////ss >> na >> nb;
    //vi a(na), b(nb);
    //vi pos(1e6+1, -1);
    //for (int i = 0; i < na; ++i) {
    //    //ptr += sscanf(ptr, "%d", &a[i]);
    //    in >> a[i];
    //}
    //for (int i = 0; i < nb; ++i) {
    //    //ptr += sscanf(ptr, "%d", &b[i]);
    //    in >> b[i];
    //    pos[b[i]] = i;
    //}

    int na, nb;
    scanf("%d %d", &na, &nb);
    vi a(na), b(nb);
    vi pos(1e6+1, -1);
    for (int i = 0; i < na; ++i) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < nb; ++i) {
        scanf("%d", &b[i]);
        pos[b[i]] = i;
    }

    int l = 0, r = 0, curpos = pos[a[l]];
    int res = 0;
    while (l < na) {
        while (l < na && pos[a[l]] == -1) {
            ++l;
            r = l;
        }
        if (l == na) break;
        if (l == r)
            curpos = pos[a[l]];
        for (;;) {
            int t = (r + 1) % na;
            if (t == l) break;
            int nextpos = pos[a[t]];
            if (nextpos == -1) break;
            /*while (nextpos <= curpos) nextpos += nb;
            if (nextpos >= pos[a[l]] + nb)
                break;*/
            if (curpos >= pos[a[l]] && nextpos <= curpos && nextpos >= pos[a[l]])
                break;
            if (curpos < pos[a[l]] && (nextpos <= curpos || nextpos >= pos[a[l]]))
                break;
            r = t;
            curpos = nextpos;
        }
        if (r >= l)
            res = max(res, r - l + 1);
        else
            res = max(res, r + na - l + 1);
        ++l;
    }
    out << res;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define ll long long
#define endl "\n"
#define all(v) (v).begin(),(v).end()
#define sz(v) (v).size()
// #define int long long
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef vector<pii> vpi;
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define d0(x) cout<<(x)<<" "
#define d1(x) cout<<(x)<<endl
#define d2(x,y) cout<<(x)<<" "<<(y)<<endl
#define d3(x,y,z) cout<<(x)<<" "<<(y)<<" "<<(z)<<endl
#define d4(a,b,c,d) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<endl
#define d5(a,b,c,d,e) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<" "<<(e)<<endl
#define d6(a,b,c,d,e,f) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<" "<<(e)<<" "<<(f)<<endl
bool desc_sort(const int & lhs,const int & rhs)
{
    return lhs>rhs;
}
bool desc_pii_sort(const pii & lhs , const pii & rhs)
{
    return lhs>rhs;
}
bool second_sort(const pii & lhs , const pii & rhs)
{
    pii a,b;
    a.F = lhs.S;
    a.S = lhs.F;
    b.F = rhs.S;
    b.S = rhs.F;
    return a<b;
}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
    os << "[ ";
    for(auto v : V) os << v << " ";
    return os << "]";
}
template<class T> ostream& operator<<(ostream &os, set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
    return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.F<<":"<<m.S<<") ";
    return os<<"}";
}
#define TRACE
#ifdef TRACE
    #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ',');
        cerr.write(names, comma - names) << " : " << arg1<<" | ";
        __f(comma+1, args...);
    }
#else
    #define trace(...)
#endif

// #define int long long
#define modd 1e0

inline ll fast_expo(ll base,ll power,ll modulo=modd){
    base%=modulo;
    if (base<0LL) base+=modulo;
    ll x=base,cnt=power,ans=1LL;
    while(cnt){
        if (cnt&1LL) ans=(ans*x)%modulo;
        x=(x*x)%modulo;
        cnt>>=1LL;
    }
    // int tmp=ans;
    return ans;
}
inline ll inv(ll base,ll modulo=modd){
    return fast_expo(base,modulo-2LL,modulo);
}

int pos[1000001];

signed main()
{
    #ifdef _SUBLIME
    ifstream cin("input.txt");
    ofstream cout("output.txt");
    #endif
    fio;
    int n,m;
    cin>>n>>m;
    int a[2*n+1],b[m+1];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        a[n+i]=a[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>b[i];
        pos[b[i]]=i;
    }
    int ans=0;
    int p1=0;
    for(int i=1;i<=n;i++)
    {
        if(pos[a[i]]>0)
        {
            p1 = max(p1,i);
            while(p1<2*n)
            {
                if(pos[a[p1+1]]==0)
                    break;
                int pa,pb;
                pa = (pos[a[p1]]-pos[a[i]]+m)%m;pa++;
                pb = (pos[a[p1+1]]-pos[a[i]]+m)%m;pb++;
                if(pa<pb)
                {
                    p1++;
                }
                else
                    break;
            }
           // trace(i,p1);
            ans = max(ans,p1-i+1);
        }
    }
    d1(ans);
    return 0;
}

#pragma comment(linker, "/stack:64000000")
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cassert>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define correct(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define ft first
#define sc second
#define X first
#define Y second

using namespace std;

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template<typename X> inline X abs(const X& a) { return a < 0? -a: a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld EPS = 1e-9, PI = 3.1415926535897932384626433832795;

const int N = 2 * 1000 * 1000 + 3;

int n, m;
int a[N], apos[N];
int b[N], bpos[N];

inline bool read()
{
	if (scanf("%d%d", &n, &m) != 2)
		return false;

	memset(apos, -1, sizeof(apos));
	memset(bpos, -1, sizeof(bpos));

	/*forn(i, n)
		a[i] = i;

    forn(i, m)
    	b[i] = i;*/

    //random_shuffle(a, a + n);
    //random_shuffle(b, b + m);

	forn(i, n)
	{
		assert(scanf("%d", &a[i]) == 1);
		apos[a[i]] = i;
		a[n + i] = a[i];
	}

	forn(i, m)
	{
		assert(scanf("%d", &b[i]) == 1);
		bpos[b[i]] = i;
		b[m + i] = b[i];
	}

	return true;
}

inline void solve()
{
	int len = 0;

	int ans = 0;

	forn(i, n)
	{
		int lf = bpos[a[i]];

		if (lf == -1)
		{
			assert(len == 0);
			continue;
		}

		if (len == 0)
			len = 1;

		int rg = bpos[a[i + len - 1]];
		(rg < lf) && (rg += m);

		while (len < n)
		{
			int pos = bpos[a[i + len]];

			if (pos == -1)
				break;

			(pos < lf) && (pos += m);

			if (lf <= pos && pos <= rg)
				break;

			rg = pos;
			len++;
		}

		ans = max(ans, len);

		len--;
	}

	cout << ans << endl;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

    assert(read());
    solve();

    return 0;
}

#pragma comment(linker, "/STACK:25600000")
#define _CRT_NO_WARNINGS
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <set>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
#define REP(i, n) for(int i=0; i<n; i++)
#define FOR(i, x, y) for(int i=x; i<=y; i++)
#define RFOR(i, x, y) for(ll i=x; i>=y; i--)
#define ALL(a) (a).begin(),(a).end()
#define pb push_back
#define PII pair<int, int>
#define PDI pair<double, int>

int a[2048000];
int b[2048000];
int pos[2048000];
int d[2048000];
int n, m;

int main()
{
	cin >> n >> m;
	FOR(i, 1, n)
	{
		scanf("%d", &a[i]);
		a[n + i] = a[i];
	}

	FOR(i, 1, m)
	{
		scanf("%d", &b[i]);
		b[m + i] = b[i];
		pos[b[i]] = i;
	}

	FOR(i, 1, 2*n)
	{
		if (pos[a[i]] == 0) continue;
		if (i == 1 || d[i-1] == 0)
		{
			d[i] = pos[a[i]];
			continue;
		}

		d[i] = pos[a[i]];
		if (d[i - 1] <= m && d[i - 1] > d[i])
			d[i] += m;

		if (d[i - 1] > m && d[i] + m > d[i - 1])
			d[i] += m;
	}

	int ans = 0;
	int p1 = 1;
	int p2 = 0;
	while(true)
	{
		++p2;
		if (p2 > 2 * n) break;

		if (d[p2] == 0)
		{
			p1 = p2 + 1;
			continue;
		}

		do {
			if (p1 + 1 >= p2) break;
			if (d[p1] > d[p2] && d[p1] - d[p2] > m) break;
			if (d[p1] < d[p2] && d[p2] - d[p1] < m) break;
			++p1;
		} while(true);

		ans = max(ans, p2 - p1 + 1);
	}
	ans = min(ans, min(n, m));
	cout << ans << endl;
}
/*
5 6
1 1 0 2 0
1 2
2 3
3 4
4 5
5 1
1 4

4 4
1 2 1 2
1 2
2 3
3 4
4 2

2 1
2 1
1 2
*/

//In the name of Allah
//
//
//////////////////////
// Program:
// Written By Alireza Farhadi (LGM)
//////////////////////
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cctype>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>
#include <bitset>
#include <deque>
#include <iomanip>
#include <complex>
#include <fstream>
#include <sstream>
#include <map>
//#include <climits>
//#include <list>

using namespace std;

#if ( _WIN32 || __WIN32__ )
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

#define show(x) cerr<<((#x))<<" = "<<((x))<<" "<<endl
#define bit(a,b) (((a)>>(b))&1)
#define gcd __gcd
#define endl '\n'
#define bcnt(x) ((__builtin_popcount(x)))
#define sz(x) ((int((x).size())))
#define sqr(x) ((((x))*((x))))
#define fx(x) fixed<<setprecision(x)

template<class T> inline void smn(T &a,const T &b){if(b<a) a=b;}
template<class T> inline void smx(T &a,const T &b){if(b>a) a=b;}
template<class T> inline T rev(const T & a){T _=a; reverse(_.begin(),_.end()); return _;}

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pie;

const double eps=1e-9;
const ld leps=1e-14;
const int MN=2*1000*1000+1000;
int n,m;
int f[MN],s[MN];
int p[MN];
int p2[MN];
pie baze[MN];
int t,res;
	set <int> st;
	set <int>::iterator it;
void chk(int a)
{
	int pt=baze[a].first;
	for (int i=baze[a+1].first;i<=baze[a+1].second;i++)
	{
		while (pt<=baze[a].second && p[f[pt]]<=p[f[i]])
			pt++;
		int l=baze[a].second-pt+1;
		l+=i-baze[a+1].first+1;
		smx(res,l);
	}
}
int main(int argc,char * argv[])
{
	ios_base::sync_with_stdio(false);
	cin>>n>>m;
	for (int i=0;i<n;i++)
		cin>>f[i];
	for (int i=0;i<m;i++)
		cin>>s[i];
	for (int i=0;i<n-1;i++)
		f[n+i]=f[i];
	f[2*n]=1000001;
	memset(p,-1,sizeof(p));
	for (int i=0;i<m;i++)
		p[s[i]]=i;
	int last=-1;
	for (int i=0;i<2*n;i++) if (p[f[i]]==-1)
	{
		if (last!=-1)
			baze[t++]=pie(last,i-1);
		last=-1;
		continue;
	}
	else
	{
		if (last==-1)
			last=i;
		else
		{
			if (p[f[i]]>p[f[i-1]])
				continue;
			baze[t++]=pie(last,i-1);
			last=i;
		}
	}
	 res=0;
	for (int i=0;i<t;i++)
		smx(res,baze[i].second-baze[i].first+1);
	for (int i=0;i<t-1;i++) if (baze[i].second+1==baze[i+1].first)
		chk(i);
	cout<<res<<endl;
	return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std ;
#define rep( i, j, k ) for( i = j ; i <= k ; ++i )
#define MaxL 1000015
#define LL long long

struct node
{
	int v, fr ;
}br[MaxL], ar[MaxL] ;
int La, Lb, ans, pre[MaxL << 1] ;
LL h[MaxL << 1] ;

inline bool cmp ( node a, node b )
{
	return ( a.v < b.v ) ;
}

int main()
{
	int i, j, l, r, mid ;

	scanf("%d%d",&La, &Lb) ;
	rep( i, 1, La )
	{
		scanf("%d", &ar[i].v) ;
		ar[i].fr = i ;
	}
	rep( i, 1, Lb )
	{
		scanf("%d", &br[i].v) ;
		br[i].fr = i ;
	}

	sort( br+1, br+1+Lb, cmp ) ;
	sort( ar+1, ar+1+La, cmp ) ;
	for( j = i = 1 ; i <= La ; ++i )
	{
		for( ; br[j].v < ar[i].v && j <= Lb ; ++j ) ;
		if( br[j].v == ar[i].v )
			h[ar[i].fr] = h[ar[i].fr+La] = br[j].fr ;
	}

	for( i = 2 ; i <= ( La << 1 ) ; ++i )
	{
		if( ! h[i] ) continue ;
		if( h[i] < h[i-1] )
			h[i] = h[i] + ( ( h[i-1] - h[i] ) / Lb + 1 ) * Lb ;
	}
	for( i = 2 ; i <= ( La << 1 ) ; ++i )
	{
		pre[i] = pre[i-1] ;
		if( h[i] > h[i-1] && h[i-1] ) ++pre[i] ;
	}

	for( i = 1 ; i <= La ; ++i ) // ö�����
	{
		if( !h[i] ) continue ;
		for( l = i, r = i + La - 1 ; l <= r ; ) // ������ ÿһ������ �� ���� ���һ�� - ��Сһ�� <= Lb
		{
			mid = ( l + r ) >> 1 ;
			if( pre[mid] - pre[i] == mid - i && h[mid] - h[i] < Lb )
				l = mid + 1 ;
			else
				r = mid - 1 ;
		}
		ans = max( ans, l-i ) ;
	}

	printf("%d\n",ans) ;
//	system("pause") ;
	return 0 ;
}

/*
You were daddy's girl nice and sweet
Never in trouble mommy's honey
Little child who just couldn't see
The pressure from her so called friends
Was simply too much

The monkey slowly climbed on her back
Offering an aid for her pain
Giving love and care
No-one cared, no-one cared...

Fragile like a rose on the snow
Eating all your strength and your money
Walking in the shade day and night
Never letting sunshine in your eyes like before

Cannot shake the monkey off your back
Did I see a spark on your eye
Was it just the last light of hope
That died, hope that died

"Forgive me, Father, my daily sin..."

How can I forgive you, never leave you
You know that if you live like, you will die like
Haven of Emotion, Mournful Ocean
Heiress of the Evening Sings in silence

"I need to have now, my daily sin..."

For all your life I prayed for time
To show you where the light lies
Now this is the end
One rose for the memory of the innosence...

"I know, my Father, I cannot win..."

Never will forgive you, never leave you
You know that if you live like, you will die like
How can I erase your pain and aid you
When Death wants to kiss you and you want kiss Him back...
*/

//#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#define y1 aasdfasdfasdf
#define yn askfhwqriuperikldjk
#define  INF 1000000000
#define eps 1e-8
//#define M_PI 3.141592653589793
//#define mx 1000000000000ll
#define bs 1000000007
//#define szz 400
//#define pb push_back
using namespace std;
long n,m,ar1[2200000],c,ar2[2200000],ps[2200000],h[2200000],l,r,cur,ans;
vector <long> v;
int main(){
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
cin>>n>>m;

for (int i=0;i<n;i++)
{scanf("%d",&ar1[i]);
}

for (int i=0;i<m;i++)
{scanf("%d",&ar2[i]);ps[ar2[i]]=i+1;
}

for (int i=n;i<n*2;i++)
ar1[i]=ar1[i-n];

for (int i=0;i<n*2;i++)
h[i]=ps[ar1[i]];

cur=0;

while (cur<n*2)
{
      v.erase(v.begin(),v.end());
      while (h[cur]!=0)
      {v.push_back(h[cur]);cur++;
      }
 //  cout<<v.size()<<" "<<cur<<endl;
// for (int i=0;i<v.size();i++)cout<<v[i]<<" ";
 // cout<<endl;

      cur++;c=0;
      if (v.size())
      {
                   l=r=0;
                   while (r+1<v.size()&&v[r]<v[r+1])++r;
                 if (r+1<v.size()&&v[r+1]<v[l]){c=1;  ++r; }
                   while (r+1<v.size()&&v[r+1]<v[0]&&v[r+1]>v[r])++r;
                   ans=max(ans,r-l+1);
                //  cout<<r<<" "<<l<<endl;
                   while (l+1<v.size())
                   {
                         if (v[l+1]>v[l]){
                                          ++l;
                                          while (r+1<v.size()&&v[r+1]<v[l]&&v[r+1]>v[r])++r;
                                          if (r+1<v.size()&&c==0&&v[r+1]<v[r]&&v[r+1]<v[l]){r++;c=1;}
                                          while (r+1<v.size()&&v[r+1]<v[l]&&v[r+1]>v[r])++r;
                                          }
                         else
                         {
                            ++l;c=0;
                            while (v[r]<v[r+1]&&r<v.size())++r;
                                              if (r+1<v.size()&&v[r+1]<v[l]){++r;c=1;}

                            while (r+1<v.size()&&v[r]<v[r+1]&&v[r+1]<v[l])++r;

                         }
                         ans=max(ans,r-l+1);
                      //  cout<<r<<" "<<l<<endl;
                   }
      }
}

cout<<ans<<endl;

cin.get();cin.get();
return 0;}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using ld = long double;
#define all(x) (x).begin(),(x).end()
const int MN = 1e6+3, MOD = 1e9+7;
mt19937_64 rnd = mt19937_64(chrono::steady_clock::now().time_since_epoch().count());
int main() {
    int n,m;
    scanf ("%d %d",&n,&m);
    vector<int> a(n+1), eds(n+1), aidx(MN), b;
    for (int i = 1; i <= n; i++) scanf ("%d",&a[i]), aidx[a[i]] = i;
    for (int i = 1; i <= m; i++) {
		int c;
		scanf ("%d",&c);
		if (aidx[c]) b.push_back(aidx[c]);
	}
	int m0 = b.size(), ret = 0; vector<int> bidx(MN);
	for (int i = 0; i < m0; i++) b.push_back(b[i]), bidx[b[i]] = i;
	auto lst = [&] (int aa) {return aa == 1 ? n : aa-1;};
	auto ree = [&] (int aa) {return aa <= 0 ? aa + n : aa;};
	for (int i = 0; i < b.size(); i++) {
		eds[b[i]] = eds[lst(b[i])] + 1;
		while (eds[b[i]] > 1 && bidx[ree(b[i]-eds[b[i]]+1)]+m0-1 < i) --eds[b[i]];
		ret = max(ret,eds[b[i]]);
	}
    printf ("%d\n",ret);
    return 0;
}

#include<cmath>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<sstream>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<time.h>
#include<stdlib.h>
#include<assert.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define rep(i,l,r) for(int i=(l);i<(r);++i)
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e6 + 7;
const int INF = 1e9 + 7;
const int MOD = 1e9 + 7;
const double Pi = acos(-1.0);
const double EPS = 1e-8;
//--------head--------
int n, m, a[N << 1], R[N];
int h[2], t[2], que[N << 1];
int main() {
	scanf("%d%d", &n, &m);
	rep(i, 0, n)
		scanf("%d", a + i);
	memset(R, -1, sizeof(R));
	rep(i, 0, m) {
		int x;
		scanf("%d", &x);
		R[x] = i;
	}
	rep(i, 0, n)
		a[i] = a[n + i] = R[a[i]];
	a[n << 1] = -1;
	//	rep(i, 0, 2 * n) printf("%d ", a[i]);puts("");
	int ans = 0;
	for (int i = 0; i < n; ++i) {
		if (a[i] == -1)
			continue;
		ans = max(ans, 1);
		int j, w = 0;
		h[0] = t[0] = 0, h[1] = t[1] = n;
		que[t[0]++] = a[i];
		for (j = i + 1; ~a[j] && j < (n << 1); ++j) {
			if (a[j] <= que[t[w] - 1]) {
				if (w == 1) {
					swap(h[0], h[1]), swap(t[0], t[1]);
					h[1] = t[1] = (h[0] >= n ? 0 : n);
				}
				w = 1;
			}
			if (w == 1)
				while (h[0] < t[0] && que[h[0]] <= a[j])
					++h[0];
			que[t[w]++] = a[j];
			ans = max(ans, (t[0] - h[0]) + (t[1] - h[1]));
		}
		i = j;
	}
	printf("%d", ans);
	return 0;
}

#ifdef NALP_PROJECT
#pragma hdrstop
#else
#define _SECURE_SCL 0
#endif

#define _CRT_SECURE_NO_DEPRECATE
#pragma comment(linker, "/STACK:64000000")

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <utility>

#include <set>
#include <map>
#include <vector>
#include <string>
#include <queue>
#include <memory.h>

#include <iostream>
#include <sstream>

using namespace std;

typedef long long int64;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define y1 YYYYYYYYYYYY1
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define Abs(x) (((x) >= 0) ? (x) : (-(x)))

const int INF = (int)1E9;
const int64 INF64 = (int64)1E18;
const long double EPS = 1E-9;
const long double PI = 3.1415926535897932384626433832795;

const int MAXN = 2001000;

int n1, n2, a1[MAXN], a2[MAXN], pos[MAXN];

int main() {
#ifdef NALP_PROJECT
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#else
#endif

	cin >> n1 >> n2;
	forn(i, n1) {
		scanf("%d", &a1[i]);
		a1[n1 + i] = a1[i];
	}

	memset(pos, 255, sizeof pos);
	forn(i, n2) {
		scanf("%d", &a2[i]);
		a2[n2 + i] = a2[i];
		pos[a2[i]] = i;
	}

	int ans = 0, r = 0, last = -1, len = 0;
	forn(l, n1) {
		while (r - l < n1) {
			if (pos[a1[r]] == -1) break;

			if (r == l) {
				len = 1;
				r++;
			} else {
				int cur = (pos[a1[r]] - pos[a1[r - 1]] + n2) % n2;
				if (cur + len > n2) break;
				len += cur;
				r++;
			}
		}

		ans = max(ans, r - l);
		if (r == l)
			r++;
		else if (r - l > 1)
			len -= (pos[a1[l + 1]] - pos[a1[l]] + n2) % n2;
	}

	cout << ans << endl;

	return 0;
}

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <cassert>
#include <numeric>
#include <string>
#include <cstring>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long int int64;

const int N = (int)2e6 + 100;

int n, m;
int str1[N], str2[N];

int pos[N];

bool in_seg(int x, int l, int r)
{
	if (l < r)
		return l <= x && x < r;
	return x >= l || x < r;
}

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
#endif

	scanf("%d%d", &n, &m);

	for (int i = 0; i < n; i++)
		scanf("%d", &str1[i]);
	for (int i = 0; i < n; i++)
		str1[n + i] = str1[i];

	for (int i = 0; i < m; i++)
		scanf("%d", &str2[i]);

	for (int i = 0; i < N; i++)
		pos[i] = -1;
	for (int i = 0; i < m; i++)
		pos[str2[i]] = i;

	int ans = 0;

	int r1 = 0;
	int l2 = -1;
	int r2 = -1;

	for (int l1 = 0; l1 < n; l1++)
	{
		//printf("l1 = %d r1 = %d l2 = %d r2 = %d\n", l1, r1, l2, r2);

		while (true)
		{
			int c = str1[r1];
			int p = pos[c];

			if (p == -1)
				break;

			if (l2 != -1 && in_seg(p, l2, r2))
				break;

			if (l2 == -1)
				l2 = p;

			r2 = (p + 1) % m;
			r1++;
		}

		//printf("l1 = %d r1 = %d l2 = %d r2 = %d\n", l1, r1, l2, r2);

		ans = max(ans, r1 - l1);

		if (l1 == r1)
		{
			r1++;
			continue;
		}

		if (l1 == r1 - 1)
		{
			l2 = -1;
			r2 = -1;
			continue;
		}

		int c = str1[l1 + 1];
		l2 = pos[c] % m;
	}

	printf("%d\n", ans);

	return 0;
}

#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <queue>
#include <memory.h>
#include <stack>
#define mp make_pair
#define pb push_back
#define setval(a,v) memset(a,v,sizeof(a))

#if ( _WIN32 || __WIN32__ )
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

using namespace std;

typedef long long ll;
typedef long double ld;

const ll inf = (1LL<<60);

const int MAXN = 1100000;

int a[MAXN];
int b[MAXN];

int n,m;

struct myst{
    vector<pair<ll,ll> > v;

    myst(){
        v.pb(mp(inf,inf));
    }

    bool empty(){
        return (int)v.size() == 1;
    }

    void push(ll x){
        v.pb(mp(x,min(x,v.back().second)));
    }

    ll pop(){
        ll temp = v.back().first;
        v.pop_back();
        return temp;
    }

    ll val(){
        return v.back().second;
    }

    void clear(){
        v.resize(1);
    }

    int size(){
        return (int)v.size()-1;
    }
};

struct myqu{
    myst a,b;

    myqu():a(),b(){
    }

    void push(ll x){
        a.push(x);
    }

    void pop(){
        if (b.empty()){
            while (!a.empty())
                b.push(a.pop());
        }
        b.pop();
    }

    ll val(){
        return min(a.val(),b.val());
    }

    void clear(){
        a.clear();
        b.clear();
    }

    int size(){
        return a.size()+b.size();
    }
};

int main(){
  #ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
  #endif

    scanf("%d %d",&n,&m);
    memset(a,-1,sizeof(a));
    for (int i = 0; i < n; i++){
        int t;
        scanf("%d",&t);
        a[t] = i;
    }
    memset(b,-1,sizeof(b));
    for (int i = 0; i < m; i++){
        int t;
        scanf("%d",&t);
        if (a[t] != -1)
            b[a[t]] = i;
    }

    int ans = 0;

    ll cur = 0;

    myqu q;

    for (int R = 0;R < 2*n; R++){
        int r = R % n;
        if (b[r] == -1){
            q.clear();
            continue;
        }

        ll cur1 = b[r] + ((cur - b[r])/m)*1LL*m;
        while (cur1 <= cur)
            cur1+=m;

        q.push(cur1);

        cur = cur1;

//        cerr << cur << endl;

        while (cur  - q.val() >= m)
            q.pop();

        ans = max(ans,q.size());
    }

    printf("%d\n",ans);
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker,"/STACK:16000000")
#include <algorithm>
#include <numeric>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <sstream>

using namespace std;

#define REP(i,n) for (int i=0,_n=(n); i < _n; i++)
#define REPD(i,n) for (int i=(n)-1; i >= 0; i--)
#define FOR(i,a,b) for (int _b=(b), i=(a); i <= _b; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))

#define CLEAR(x) memset(x,0,sizeof x);
#define CLEARA(x) memset(&x,0,sizeof x);
#define FILL(x,v) memset(x,v,sizeof x);
#define FILLA(x,v) memset(&x,v,sizeof x);

#define VAR(a,b) __typeof(b) a=(b)
#define FOREACH(it,c) for(VAR(it,(c).begin());it!=(c).end();++it)

#define REVERSE(c) reverse(ALL(c))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define INF 0x7fffffff
#define X first
#define Y second
#define pb push_back
#define SZ(c) (int)(c).size()
#define MP make_pair
#define eps 1.0e-11
const double pi = acos(-1.0);

typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef long long LL;

#define N 1024000
int n1,n2,a1[N],a2[N],id1[N],id2[N];

int main()
{
	scanf("%d%d",&n1,&n2);
	FILL(id1,-1);
	FILL(id2,-1);
	REP(i,n1)
	{
		scanf("%d",a1+i);
		id1[a1[i]]=i;
	}
	REP(i,n2)
	{
		scanf("%d",a2+i);
		id2[a2[i]]=i;
	}
	deque<LL> q;
	int res = 0;
	REP(i,n1*2)
	{
		int c = a1[i%n1];
		LL x = id2[c];
		if (x == -1)
			q.clear();
		else
		{
			if (!q.empty())
			{
				x += q.front()/n2*n2;
				while (x <= q.front())
					x += n2;
				while (!q.empty() && x-q.back() >= n2)
					q.pop_back();
			}
			q.push_front(x);
			while (SZ(q) > n1) q.pop_back();
			res = max(res,SZ(q));
		}
	}
	printf("%d\n",res);
	return 0;
}

#include <algorithm>
#include <cstring>
#include <cstdio>

#define MAXN 1000000

using namespace std;

int L1, L2;
int v[2*MAXN + 1], pos[MAXN + 1];

bool valid(int p, int q, int nq)
{
	if(nq == -1) return 0;
	else
	{
		if(p > q) q += L2;
		if(q > nq) nq += L2;

		return q <= nq && nq - p < L2;
	}
}

int main()
{
	while(scanf("%d %d", &L1, &L2) == 2)
	{
		for(int i=0; i<L1; i++)
		{
			scanf("%d", &v[i]);
			v[i+L1] = v[i];
		}

		memset(pos, -1, sizeof(pos));

		for(int i=0; i<L2; i++)
		{
			int tmp;
			scanf("%d", &tmp);
			pos[tmp] = i;
		}

		int i = 0, j = 0, maxN = 0;

		while(i < L1)
		{
			if(pos[v[i]] != -1)
			{
				if(j < i) j = i;

				while(j + 1 - i < L1 && valid(pos[v[i]], pos[v[j]], pos[v[j+1]])) j++;

				maxN = max(maxN, j - i + 1);
			}

			i++;
		}

		printf("%d\n", maxN);
	}

	return 0;
}

#include<stdio.h>
#include<algorithm>
using namespace std;

int a[2000005],pos[1000100]={0};
bool in_subseq(int x,int l,int r)
{
    if(l<=r) return (l<=x && x<=r);
    return (l<=x || x<=r);
}

int main()
{
    int m,n,i,j,ans=0;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;++i)
    {
        scanf("%d",&a[i]);
        a[i+m]=a[i];
    }
    for(i=1;i<=n;++i)
    {
        scanf("%d",&j);
        pos[j]=i;
    }
    for(i=1,j=2;i<=m;++i) if(pos[a[i]])
    {
        j=max(j,i+1);
        while(j<i+m && pos[a[j]] && !in_subseq(pos[a[j]],pos[a[i]],pos[a[j-1]])) ++j;
        ans=max(ans,j-i);
    }
    printf("%d",ans);
}

/* -*- coding: utf-8 -*-
 *
 * 0164B.cc: B. Ancient Berland Hieroglyphs
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

const int MAX_N = 1000000;
const int MAX_N2 = MAX_N * 2;
const int MAX_M = 1000000;

/* typedef */

typedef long long ll;
typedef pair<int,int> pii;

/* global variables */

int as[MAX_N];
ll bjs[MAX_N2];
pii bs[MAX_M];

/* subroutines */

/* main */

int main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  int n, m;
  scanf("%d%d", &n, &m);

  for (int i = 0; i < n; i++) scanf("%d", as + i);
  for (int i = 0; i < m; i++) scanf("%d", &bs[i].first), bs[i].second = i;
  sort(bs, bs + m);

  for (int i = 0; i < n; i++) {
    int k = lower_bound(bs, bs + m, pii(as[i], 0)) - bs;
    bjs[i] = bjs[i + n] = (k >= m || bs[k].first != as[i]) ? -1 : bs[k].second;
  }

  int n2 = n * 2;
  ll pj = 0;
  for (int i = 0; i < n2; i++) {
    if (bjs[i] < 0) pj = 0;
    else {
      if (pj > bjs[i]) bjs[i] += (pj - bjs[i] + m - 1) / m * m;
      pj = bjs[i];
    }
  }

  int maxl = 0, lim = min(n, m);
  for (int i = 0, j = 0; i < n2; i++) {
    if (bjs[i] < 0) j = i + 1;
    else {
      while (j < n2 && bjs[j] >= 0 && bjs[i] + m > bjs[j]) j++;
      int l = j - i;
      //printf("i=%d, j=%d\n", i, j);
      if (maxl < l) maxl = l;
      if (maxl >= lim) {
	maxl = lim;
	break;
      }
    }
  }

  printf("%d\n", maxl);
  return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 2e6 + 1;
const int L = 20;
int n, m, ans;

int nxt[N][L];
int lst[N];

int a[N];
int b[N];
int c[N];

void input() {
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    for(int i = 1; i <= m; ++i) {
        cin >> b[i];
    }
}

int bin_lift(int s) {
    int res = 0;
    int lim = s + m;
    for(int i = L - 1; i >= 0; --i) {
        if(!nxt[s][i]) {
            continue;
        }
        if(nxt[s][i] < lim) {
            s = nxt[s][i];
            res += 1 << i;
        }
    }
    return res + 1;
}

void solve() {
    for(int i = 1; i < n; ++i) {
        c[a[i]] = a[i + 1];
    }
    c[a[n]] = a[1];
    for(int i = m + 1; i <= 2 * m; ++i) {
        b[i] = b[i - m];
    }
    for(int i = 2 * m; i >= 1; --i) {
        int x = c[b[i]];
        if(!x) {
            continue;
        }
        nxt[i][0] = lst[x];
        for(int j = 1; j < L; ++j) {
            nxt[i][j] = nxt[nxt[i][j - 1]][j - 1];
        }
        ans = max(ans, bin_lift(i));
        lst[b[i]] = i;
    }
    cout << ans << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1100000

int a[2*MAXN],b[2*MAXN],n,m,Ans,f[MAXN];

long long Q[2*MAXN];

char Chr;

void read(int&x)
{	for(;(Chr=getchar())<'0';);
	for(x=Chr-'0';(Chr=getchar())>='0';x=x*10+Chr-'0');
}

int main()
{	int i,k,l;
long long j;
	//freopen("b.in","rb",stdin);
	//freopen("b.out","wb",stdout);
	read(n);
	read(m);
	for(i=0;i<n;i++)read(a[i]);
	for(i=0;i<n;i++)a[i+n]=a[i];
	for(i=0;i<m;i++)read(b[i]);
	memset(f,-1,sizeof f);
	for(i=0;i<m;i++)f[b[i]]=i;
	for(i=k=0;i<n;i++)if(f[a[i]]!=-1)
	{	if(k<=i){k=i+1;Q[i]=f[a[i]];}
		for(;k<i+n&&f[a[k]]!=-1;k++)
		{	j=(Q[k-1]/m)*m+f[a[k]];
			if(j<=Q[k-1])j+=m;
			Q[k]=j;
			if(Q[k]>=Q[i]+m)break;
		}
		if(k-i>Ans)Ans=k-i;
	}
	printf("%d\n",Ans);
	return 0;
}

#pragma comment (linker, "/STACK:100000000")
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <memory.h>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

#define FOR(i,a,b) for(int (i) = (a); (i) < (b); ++(i))
#define RFOR(i,a,b) for(int (i) = (a)-1; (i) >= (b); --(i))
#define CLEAR(a) memset((a),0,sizeof(a))
#define INF 1000000000
#define PB push_back
#define ALL(c) (c).begin(), (c).end()
#define pi 2*acos(0.0)
#define SQR(a) (a)*(a)
#define MP make_pair
#define MAX 2000007

typedef long long Int;

int n, m;
int A[MAX];
int B[MAX];
int P[MAX];
Int X[MAX];

int main()
{
	cin >> n >> m;
	FOR (i,0,n)
	{
		scanf("%d", &A[i]);
		A[n+i] = A[i];
	}

	memset(P, -1, sizeof(P));
	FOR (i,0,m)
	{
		scanf("%d", &B[i]);
		P[B[i]] = i;
	}

	FOR (i,0,n+n)
	{
		X[i] = P[A[i]];
		if (X[i] == -1)
			continue;
		if (i > 0 && X[i-1] == -1)
			continue;
		if (i > 0 && X[i] <= X[i-1])
		{
			Int d = (X[i-1] - X[i])/m;
			d++;
			X[i] += d*m;
 		}
	}

	int res = 0, Max = -1;
	FOR (i,0,n)
	{
		if (X[i] == -1)
		{
			Max = -1;
			continue;
		}
		if (Max == -1)
			Max = i;
		if (Max < i)
			Max = i;
		while (Max < n+n && X[Max] != -1 && X[Max] - X[i] < m)
			Max++;
		res = max(res, Max-i);
	}

	cout << res << endl;

	return 0;
}

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <deque>
using namespace std;

#define MAXN 1000005

typedef long long LL;

int la, lb;
int a[MAXN * 2], b[MAXN];
LL pos[MAXN];
deque<LL> q;

int main()
{
    scanf("%d%d", &la, &lb);
    memset(pos, -1, sizeof(pos));
    for(int i = 0; i < la; i++)
    {
        scanf("%d", &a[i]);
        a[i + la] = a[i];
    }
    for(int i = 0; i < lb; i++)
    {
        scanf("%d", &b[i]);
        pos[b[i]] = i;
    }
    int ans = 0;
    LL l = 0, r = -1, t = 0;
    while (r < 2 * la)
    {
        r++;
        if (pos[a[r]] == -1)
        {
            l = r + 1;
            q.clear();
            t = 0;
            continue;
        }
        LL R = pos[a[r]] + t * lb;
        if (!q.empty())
        {
            while (R < q.back()) R += lb;
        }
        q.push_back(R);
        while (r - l >= la)
        {
            q.pop_front();
            l++;
        }
        while (q.back() - q.front() >= lb)
        {
            q.pop_front();
            l++;
        }
        t = q.front() / lb;
        if (r - l + 1 > ans) ans = r - l + 1;
    }
    cout << ans << endl;

    return 0;
}

#include<stdio.h>
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<memory.h>
#include<map>
#include<set>
#include<queue>
#include<list>
#include<sstream>
#define mp make_pair
#define pb push_back
#define F first
#define S second
#define SS stringstream
#define sqr(x) ((x)*(x))
#define m0(x) memset(x,0,sizeof(x))
#define m1(x) memset(x,63,sizeof(x))
#define CC(x) cout << (x) << endl
#define AL(x) x.begin(),x.end()
#define pw(x) (1ull<<(x))
#define M 1000000007
using namespace std;
typedef pair<int,int> pt;
typedef vector<int> vt;

int ans,n,m,a[2111111],b[2111111],bb[2111111],s,l,r,o,e[2111111];

int main(){
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	cin >> n >> m;
	for (int i=0;i<n;i++)scanf("%d",&a[i]);
	for (int i=0;i<m;i++)scanf("%d",&b[i]);
	for (int i=0;i<n;i++)a[i+n]=a[i];
	for (int i=0;i<m;i++)bb[b[i]]=i+1;
	for (int i=0;i<n+n;i++){
		s=bb[a[i]];
		if (!s){
			l=r=o=0;
			continue;
		}
		e[++r]=s;
		if (r-l>1&&e[r]<=e[r-1])o++;
		while (o>1||o&&e[r]>=e[l+1]){
			if (e[l+1]>e[l+2])o--;
			l++;
		}
		ans=max(ans,r-l);
	}
	CC(ans);
	return 0;
}

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <complex>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <string>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

#define all(x) (x).begin(), (x).end()
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); it++)

#ifdef KAZAR
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
    #define eprintf(...) 0
#endif

using namespace std;

template<class T> inline void umax(T &a,T b){if(a<b) a = b ; }
template<class T> inline void umin(T &a,T b){if(a>b) a = b ; }
template<class T> inline T abs(T a){return a>0 ? a : -a;}
template<class T> inline T gcd(T a,T b){return __gcd(a, b);}
template<class T> inline T lcm(T a,T b){return a/gcd(a,b)*b;}

typedef long long ll;
typedef pair<int, int> ii;

const int inf = 1e9 + 143;
const ll longinf = 1e18 + 143;

inline int read(){int x;scanf(" %d",&x);return x;}

const int N = 1 << 21;

int n, m;
int a[N], pos[N];
int match[N];

bool good(int a,int b,int c){
    if(a <= b){
        return c < a || c > b;
    }else{
        return c > b && c < a;
    }
}

int main(){

#ifdef KAZAR
    freopen("f.input","r",stdin);
    freopen("f.output","w",stdout);
    freopen("error","w",stderr);
#endif

    n = read();
    m = read();

    for(int i = 0; i < n; i++)
        a[i] = read();

    memset(pos, -1, sizeof pos);
    for(int i = 0; i < m; i++){
        int x = read();
        pos[x] = i;
    }

    for(int i = 0; i < n; i++){
        a[i] = pos[a[i]];
    }
    for(int i = n; i < n + n; i++)
        a[i] = a[i - n];

    int ans = 0;
    int R = -1;
    for(int L = 0; L < n; L++){
        if(a[L] == -1){
            R = L;
            continue;
        }
        if(R < L){
            R = L;
        }
        while(R + 1 < L + n && a[R + 1] != -1 && good(a[L], a[R], a[R + 1])){
            ++R;
        }
        eprintf("L = %d, R = %d\n", L, R);
        umax(ans, R - L + 1);
    }

    printf("%d\n", ans);

    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>

#define MAXN 1000000

using namespace std;

int L1, L2;
int v[2*MAXN + 1], pos[MAXN + 1];

bool valid(int p, int q, int nq)
{
	if(nq == -1) return 0;
	else
	{
		if(p > q) q += L2;
		if(q > nq) nq += L2;

		return p <= q && q <= nq && nq - p < L2;
	}
}

int main()
{
	while(scanf("%d %d", &L1, &L2) == 2)
	{
		for(int i=0; i<L1; i++)
		{
			scanf("%d", &v[i]);
			v[i+L1] = v[i];
		}

		memset(pos, -1, sizeof(pos));

		for(int i=0; i<L2; i++)
		{
			int tmp;
			scanf("%d", &tmp);
			pos[tmp] = i;
		}

		int i = 0, j = 0;
		int p = pos[v[0]], q = pos[v[0]];
		int maxN = (p != -1);

		while(i < L1)
		{
			p = pos[v[i]];

			if(p != -1)
			{
				if(j < i)
				{
					j = i;
					q = pos[v[j]];
				}

				while(j + 1 - i < L1 && valid(p, q, pos[v[j+1]]))
				{
					j = j + 1;
					q = pos[v[j]];
					maxN = max(maxN, j-i+1);
				}
			}

			i++;
		}

		cout<<maxN<<endl;
	}

	return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
using namespace std;

int m1[2000005];
int m2[2000005];
int pos1[1000005];
int pos2[1000005];
int ans[2000005];
int parent[2000005];
int n1, n2;

int main()
{
//  memset(ans, -1, sizeof(ans));
    scanf("%d%d", &n1, &n2);
    int i;
    for(i = 1; i <= n1; i++)
    {
        scanf("%d", m1 + i);
        m1[n1 + i] = m1[i];
        pos1[m1[i]] = i;
    }
    for(i = 1; i <= n2; i++)
    {
        scanf("%d", m2 + i);
        m2[n2 + i] = m2[i];
        pos2[m2[i]] = i;
    }
    int res = 0;
    int st = 1;
    for(i = 1; i <= n1 + n1; i++)
    {
        int p2 = pos2[m1[i]];
        int t = 0;
        if(p2)
        {
            if(ans[i - 1])
            {
                p2 += (parent[i - 1] - 1) / n2 * n2;
                if(parent[i - 1] >= p2)
                {
                    p2 += n2;
                }
                while(st < i && p2 - parent[st] + 1 > n2) st++;
                t = i - st + 1;
                parent[i] = p2;
            }
            else
            {
                t = 1;
                st = i;
                parent[i] = p2;
            }
        }
//      cout << i << ' ' << st << ' ' << parent[i] << endl;
        ans[i] = t;
//      cout << ans[i] << ' ' << parent[i] << endl;
        if(ans[i] > res) res = ans[i];
    }
    printf("%d\n", res);
    return 0;
}

/*
* Problem:
* Author: Leo Yu
* Time:
* State:
* Memo:
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
inline int   read()
{
	int x = 0;	char ch = getchar();	bool positive = 1;
	for (; ch < '0' || ch > '9'; ch = getchar())  if (ch == '-')  positive = 0;
	for (; ch >= '0' && ch <= '9'; ch = getchar())    x = x * 10 + ch - '0';
	return positive ? x : -x;
}
#define link Link
#define next Next

int N, M, a[2000006], pos[2000006];

bool	in_segment(int l, int r, int x)
{
	if (l <= r)	return x >= l && x <= r;
	return x >= l || x <= r;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif

	N = read(), M = read();
	for (int i = 1; i <= N; ++ i)	a[i] = a[i + N] = read();
	for (int j = 1; j <= M; ++ j)	pos[read()] = j;
	int l = 0, r = 0;
	int ans = 0;
	for (int i = 1, j = 1; i <= N; ++ i)	if (pos[a[i]])
	{
		l = pos[a[i]];
		if (j <= i)	j = i + 1, r = pos[a[i]];
		while (j < i + N && pos[a[j]] && !in_segment(l, r, pos[a[j]]))
			r = pos[a[j ++]];
		ans = max(ans, j - i);
	}
	cout << ans << endl;

	return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <type_traits>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define En printf("\n")
#define P(a) printf("%d ",a)
#define read(a) scanf("%d", &a)
#define readll(a) scanf("%lld", &a)
#define reads(s) scanf("%s", s)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define rep(flag, a, b) for (int flag = (a); flag <= (b); ++flag)
#define Rep(flag, a, b) for (int flag = (a); flag >= (b); --flag)

const int MAX = 1000020;
int a[MAX], b[MAX];
int la, lb;
unordered_map<int, int> mapb;

#define next(i) (i == la? 1 : i + 1)
#define prev(i) (i == 1? la : i - 1)

bool validPos(int pos, int left, int right) {
    if (left == right) {
        return 1;
    } else {
        if (left < right) {
            if ((pos >= 1 && pos < left) || (pos > right && pos <= la)) return 1;
            else return 0;
        } else {
            if (pos > right && pos < left) return 1;
            else return 0;
        }
    }
}

int distance(int left, int right) {
    if (left <= right) return right - left + 1;
    else return la - left + 1 + right;
}

int main() {
    scanf("%d%d", &la, &lb);
    rep (i, 1, la) scanf("%d", &a[i]);
    rep (i, 1, lb) scanf("%d", &b[i]), mapb[b[i]] = i;
    int pos = 1, lim;
    int left, right;
    auto end = mapb.end();
    int ans = 0;
    do {
        bool debug = 0;
        if (pos == 3) debug = 1;
        if (pos == 1) {
            if (mapb.find(a[pos]) == end) lim = 0;
            else {
                lim = pos, left = mapb[a[pos]], right = left;
                while (next(lim) != pos) {
                    int tmp = a[next(lim)];
                    if (mapb.find(tmp) == end) break;
                    else {
                        int nextPos = mapb[tmp];
                        if (validPos(nextPos, left, right)) lim = next(lim), right = nextPos;
                        else break;
                    }
                }
            }
        } else {
            if (lim == 0 || lim == prev(pos)) {
                if (mapb.find(a[pos]) == end) lim = 0;
                else {
                    lim = pos, left = mapb[a[pos]], right = left;
                    while (next(lim) != pos) {
                        int tmp = a[next(lim)];
                        if (mapb.find(tmp) == end) break;
                        else {
                            int nextPos = mapb[tmp];
                            if (validPos(nextPos, left, right)) lim = next(lim), right = nextPos;
                            else break;
                        }
                    }
                }
            } else {
                left = mapb[a[pos]];
                while (next(lim) != pos) {
                    int tmp = a[next(lim)];
                    if (mapb.find(tmp) == end) break;
                    else {
                        int nextPos = mapb[tmp];
                        if (validPos(nextPos, left, right)) lim = next(lim), right = nextPos;
                        else break;
                    }
                }
            }
        }
        if (lim) ans = max(ans, distance(pos, lim));
        pos = next(pos);
    } while (pos != 1);
    Pn(ans);
    return 0;
}

#include <iostream>
#include <queue>

using namespace std;

const int Maxn = 1000 * 1000 + 10;

#define B front()
#define E back()

int d[Maxn];
int a[Maxn], b[Maxn];
int sa, sb, mx;

queue <int> q;

int main()
{
	ios::sync_with_stdio(false);
	cin >> sa >> sb;
	for(int i=0; i<sa; i++)
		cin >> a[i];
	for(int i=0; i<sb; i++)
		cin >> b[i], d[b[i]] = i + 1;

	for(int i=0; i<2 * sa; i++)
	{
		bool f=0;
		while(!f)
		{
			if(!q.size())
				f++;
			int h = d[a[i % sa]];
			if(h && q.size() < 2)
			{
				q.push(h);
				f = 1;
			}
			else if(h && q.E > q.B && (h < q.B || h > q.E))
			{
				q.push(h);
				f = 1;
			}
			else if(h && q.E < q.B && h < q.B && h > q.E)
			{
				q.push(h);
				f = 1;
			}
			if(!f)
				q.pop();
		}
		mx = max(mx, (int)q.size());
	}
	cout << min(mx, sa) << endl;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int p[1000010],a[1000010],n,m,ans;
deque<int>q;
bool in(int x,int L,int R){
    if(L<=R)return L<=x&&x<=R;
    else return x<=R||L<=x;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)scanf("%d",&a[i]);
    memset(p,-1,sizeof p);
    for(int i=0,x;i<m;++i){
        scanf("%d",&x);
        p[x]=i;
    }
    for(int i=0;i<n+n;++i){
        if(p[a[i%n]]==-1){
            q.clear();
            continue;
        }
        while(!q.empty()&&in(p[a[i%n]],q.front(),q.back()))q.pop_front();
        q.push_back(p[a[i%n]]);
        ans=max(ans,(int)q.size());
    }
    printf("%d\n",ans);
    return 0;
}

#include <cstdio>
#include <algorithm>
using namespace std;

int n,a[1000005],b[1000005];
int m,t[1000005],p[1000005];

bool seq(int i, int j, int n){
    int k=(j+1)%n;
    if(k==i || p[k]<0) return false;
    if(p[i]<=p[j] && (p[j]<p[k] || p[k]<p[i])) return true;
    if(p[i]>=p[j] && (p[j]<p[k] && p[k]<p[i])) return true;
    return false;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%d",a+i);
    fill_n(t,1000005,-1);
    for(int i=0;i<m;i++){
        scanf("%d",b+i);
        t[b[i]]=i;
    }
    for(int i=0;i<n;i++) p[i]=t[a[i]];
    int ans=0;
    for(int i=0,j=0;i<n;i++){
        if(p[i]<0) continue;
        if(j<=i) j=i;
        while(seq(i,j%n,n)) j++;
        ans=max(ans,j-i+1);
    }
    printf("%d\n",ans);
}

//lxrtxdy!
#include <cstdio>
#include <deque>

int a[1000001];
int p[1000001];

int main() {
  int l, r, i, c, v; scanf("%d%d", &l, &r);
  for (i = 0; i < l; ++i) scanf("%d", &a[i]);
  for (i = 1; i <= r; ++i) scanf("%d", &c), p[c] = i;
  std::deque<int> q;
  for (i = r = 0; i < 2*l; ++i) {
    c = p[a[i%l]];
    if (c) {
      while (q.size() >= 2 && !(q[0] < v && (v < c || c < q[0]) || q[0] > v && v < c && c < q[0]))
        q.pop_front();
      q.push_back(v=c);
    } else q.clear();
    if (q.size() > r) r = q.size();
  }
  printf("%d", l<r?l:r);
}//hellobig_tq
//orzlxr!//hello

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;

const int maxn = 1000002;
int a[maxn*2], v[maxn];

int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n, m, tmp;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; ++i)
		scanf("%d", &a[i]), a[i + n] = a[i];
	for(int i = 0; i < m; ++i)
		scanf("%d", &tmp), v[tmp] = i+1;
	int p = 0, t = 0, ans = 0;
	for(int i = 0; i < n; ++i)
	{
		if(p <= i || i >= t) p = i, t = 0;
		if(t == 0)
		{
			while(p - i + 1 <= n && v[a[p+1]] > v[a[p]] && v[a[p+1]] - v[a[i]] + 1 <= m)
				++p;
			if(p-i+1 <= n && v[a[p+1]] > 0 && v[a[p+1]] < v[a[p]] && v[a[p+1]] - v[a[i]] + 1 <= 0)
				t = p+1, p++;
		}
		if(t > 0)
		{
			while(p - i + 1 <= n && v[a[p+1]] > v[a[p]] && v[a[p+1]] - v[a[i]] + 1 <= 0)
				++p;
		}
		if(v[a[i]] > 0)
			ans = max(ans, p - i + 1);
	}
	cout << ans;

	return 0;
}

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
#include <cmath>
#include <set>
#include <ctime>
#include <algorithm>
#define min(a,b)	((a)<(b)?(a):(b))
#define max(a,b)	((a)>(b)?(a):(b))
#define abs(a)	((a)<0?-(a):(a))
#define inf 214748364
#define pi 3.141592653589793
using namespace std;
typedef long long ll;

const int maxn = 2000001;
int a[maxn],b[maxn];
int no[maxn];
int n,m;
int f[2],ff[2];
int res;

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	#endif
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d",&a[i]),a[i+n]=a[i];
	for(int i=1;i<=m;++i)
	{
		scanf("%d",&b[i]),b[i+m]=b[i];
		no[b[i]]=i;
	}
	for(int i=1;i<=n*2;++i)
	if(!no[a[i]])
		f[0]=f[1]=0;
	else
	{
		ff[0]=ff[1]=1;
		if(no[a[i]]>no[a[i-1]])
		{
			ff[0]=max(ff[0],f[0]+1);
			ff[1]=max(ff[1],f[1]+1);
		}
		ff[1]=max(ff[1],f[0]+1);
		while(ff[0]!=ff[1] && no[a[i]]>=no[a[i-ff[1]+1]])
			ff[1]--;
		f[0]=ff[0],f[1]=ff[1];
		res=max(res,f[0]);
		res=max(res,f[1]);
	}
	printf("%d\n",res);
	return 0;
}

/*
 * in the name of god
 *
 *
 *
 *
 *
 *
 *
 */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <complex>
#include <stack>
#include <deque>
#include <queue>
#include <iomanip>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef complex<double> point;
typedef long double ldb;

const int maxN = 1000 * 1000 + 10;

int n,m;
int pos[maxN],a[maxN],b[maxN],mp[maxN];

int mod (int x, int m){
	while (x>=m) x-=m;
	return x;
}

bool range (const int &l, const int &h, const int &x){
	return x>=l && x<=h;
}

int main(){

	scanf ("%d%d" , &n, &m);
	memset(mp,-1,sizeof mp);
	for (int i=0; i<n; i++) scanf("%d" , &a[i]);
	for (int i=0; i<m; i++) { scanf("%d" , &b[i]); mp[b[i]] = i; }

	for (int i=0; i<n; i++)
		pos[i] = mp[a[i]];

	int poi=-1 , ans = 0;

	for (int i=0; i<n && ans<min(n,m); i++){

		if (pos[i]==-1){
			poi = -1;
			continue;
		}

		ans = max(1,ans);

		if (poi==-1)
			poi=i;

		int lo1 = pos[i]+1 , hi1 = m-1;
		int lo2 = 0 , hi2 = pos[i]-1;

		if (poi!=i){
			if (range(lo1,hi1,pos[poi])) lo1 = pos[poi] + 1;
			else if (range(lo2,hi2,pos[poi])) { lo2 = pos[poi] + 1; hi1=-1,lo1=0; }
		}

		while (true){

			poi = (poi + 1) % n;

			if (poi==i){
				ans = n;
				break;
			}

			bool f = false;

			if (range(lo1,hi1,pos[poi])) { lo1 = pos[poi] + 1; f = true; }
			else if (range(lo2,hi2,pos[poi])) { lo2 = pos[poi] + 1; f = true; hi1=-1; lo1=0; }

			if (!f || pos[poi]==-1){
				poi = (poi-1+n)%n;
				break;
			}

		}

		if (poi<i)
			ans = max(ans , (n-i) + poi + 1);
		else if (poi>i)
			ans = max(ans , (poi-i+1));

		if (poi==i)
			poi = -1;
	}

	printf ("%d\n" , ans);

	return 0;
}

#include <iostream>
#include <cstdio>
#include <set>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <cmath>
#include <memory.h>
#include <algorithm>
#include <cstdlib>
#include <cassert>
#include <sstream>
using namespace std;
void solve();

#define pb push_back
#define mp make_pair

typedef long long li;
typedef vector<li> vi;
typedef pair<int, int> pi;

int main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output","w",stdout);
#endif
    ios_base::sync_with_stdio(false);
    int t = 1;
    //cin>>t;
    while (t--)
        solve();
    return 0;
}

int a[1010101];
int b[1010101];
int where[1010101];
void solve(){
    int n,m;
    cin>>n>>m;
    memset(where, -1, sizeof(where));
    for(int i=0;i<n;++i){
        cin>>a[i];
    }
    for(int i=0;i<m;++i){
        cin>>b[i];
        where[b[i]] = i;
    }
    int ans = 0;
    int r = 0;
    bool per = false;
    for(int l=0;l<n;++l){
        if(r<l)
            r=l;
        int start = where[a[l]];
        //cout<<' '<<l<<' '<<r<<' '<<start<<endl;
        if(start==-1){
            continue;
        }
        per = where[a[r%n]] < start;
        while(true){
            if(r == l + n){
                ans = n;
                break;
            }
            //cout<<l<<' '<<r<<' '<<start<<' '<<per<<endl;
            if(where[a[(r+1)%n]] == -1){
                ans = max(ans,r-l+1);
                break;
            }
            if(where[a[(r+1)%n]] < where[a[r%n]]){
                if(per){
                    ans = max(ans,r-l+1);
                    break;
                }
                else if(where[a[(r+1)%n]] > start){
                    ans = max(ans,r-l+1);
                    break;
                }
                else
                    per = true;
            }
            else{
                if(per){
                    if(where[a[(r+1)%n]] > start){
                        ans = max(ans, r-l +1);
                        break;
                    }
                }
            }
            ++r;
        }
        //cout<<ans<<endl;
    }
    cout<<ans;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#include <ctime>
#include <memory.h>
#include <string>
#include <sstream>
#include <map>

#define ll long long

using namespace std;

int f[1000002];
int s[1000002];
int w1[1000002];
int w2[1000002];

int main()
{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    for(int i=0;i<=1000000;++i) w1[i]=w2[i]=-1;
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i) {
        scanf("%d",&f[i]);
        w1[f[i]]=i;
    }
    for(int i=0;i<m;++i) {
        scanf("%d",&s[i]);
        w2[s[i]]=i;
    }
    int ans=0,st=-1,last=-1,len=0;
    for(int i=0;i<n;++i) {
        if (w2[f[i]]==-1) break;
        if (st==-1) {
            st=last=w2[f[i]],len=1;
        }
        else {
            int npos=w2[f[i]];
            if (npos<st) npos+=m;
            if (npos-st+1<=m&&npos>last) {
                ++len;
                last=npos;
            } else break;
        }
        if (len==n||len==m) break;
    }
    ans=len;
    int vcur=len==0 ? -1 : 1;
    for(int i=1;i<n;++i) {
        if (w2[f[i]]==-1) {
            len=0;
            st=last=-1;
            vcur=-1;
            continue;
        }
        if (vcur==-1) {
            for(int j=0;j<n;++j) {
                if (w2[f[(j+i)%n]]==-1) break;
                if (st==-1) {
                    st=last=w2[f[(j+i)%n]],len=1;
                }
                else {
                    int npos=w2[f[(j+i)%n]];
                    if (npos<st) npos+=m;
                    if (npos-st+1<=m&&npos>last) {
                        ++len;
                        last=npos;
                    } else break;
                }
                if (len==n||len==m) break;
            }
            ans=max(ans,len); vcur=1;
        } else {
            st=w2[f[i]]; --len;
            if (last-st>=m) last-=m;
            for(int j=0;j<n;++j) {
                if (w2[f[(i+len)%n]]==-1) break;
                if (st==-1) {
                    st=last=w2[f[(i+len)%n]],len=1;
                }
                else {
                    int npos=w2[f[(len+i)%n]];
                    if (npos<st) npos+=m;
                    if (npos-st+1<=m&&npos>last) {
                        ++len;
                        last=npos;
                    } else break;
                }
                if (len==n||len==m) break;
            }
            ans=max(ans,len); vcur++;
        }
//      cout << i << "  " << len << endl;
    }
    printf("%d\n",ans);
    return 0;
}

#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <utility>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <ctime>
#include <queue>
#include <cmath>
#include <deque>
#include <list>
#include <sstream>
#include <bitset>
#include <complex>
#pragma comment(linker, "/STACK:16777216")
#pragma warning(default :4)
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define eps 1e-9
#define INF 1000000001
#define oo 1000000001
#define MOD 1000000007
#define cint const int &
#define cll const ll &
#define cull const ull &
#define FOR(i, x) for (int i = 0; i < (int)(x); ++i)
#define CL(x) memset(x, 0, sizeof(x))
#define SVAL(x, y) memset(x, y, sizeof(x))
#define FIN freopen("in.txt", "r", stdin);
#define FOUT freopen("out.txt", "w", stdout);
#define y1 Y1
using namespace std;
typedef vector<int> VINT;
typedef pair<int, int> PII;
typedef complex<double> Cn;
int n, m, s1[1<<21], s2[1<<21], r, p2[1<<21]; ll q[1<<21];
int main()
{
    SVAL(p2, -1);
    scanf("%d %d", &n, &m);
    FOR(i, n)
    {
        scanf("%d", s1+i);
        s1[n+i]=s1[i];
    }
    FOR(i, m)
    {
        scanf("%d", s2+i);
        s2[m+i]=s2[i];
        p2[s2[i]]=i;
    }
    int ql, qr;
    ql=qr=0;
    FOR(i, 2*n)
    {
        int &p=p2[s1[i]];
        if (p==-1)
        {
            ql=qr=0;
            continue;
        }
        q[qr]=q[qr-1]/m*m+p; if (qr) while (q[qr]<q[qr-1]) q[qr]+=m;
        if (q[qr++]-q[ql]>m) ql++;
        r=max(r, qr-ql);
    }
    printf("%d\n", min(r, n));
    return 0;
}

										/* in the name of Allah */
#include <iostream>
#include <memory.h>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

#define int64 long long
#define P pair<int, int>
#define Max 1000010

int n, m;
int a[Max], b[Max];
int mp[Max], idx[Max];

int main(){
	cin >> n >> m;
	memset(idx, -1, sizeof idx);
	memset(mp, -1, sizeof mp);
	for(int i = 0; i < n; i++){
		scanf("%d", &a[i]);
		mp[a[i]] = i;
	}
	for(int i = 0; i < m; i++){
		scanf("%d", &b[i]);
		if(mp[b[i]] != -1)
			idx[mp[b[i]]] = i;
	}
	int mx = 0;
	for(int str = 0, end = 1; str < n; str++){
		if(idx[str] == -1){
			end = (str + 2) % n;
			continue;
		}
		int pend = (end == 0 ? n - 1 : end - 1);
		while(idx[end] != -1 && end != str){
			if(idx[pend] >= idx[str] && idx[end] < idx[pend] && idx[end] > idx[str])
				break;
			if(idx[pend] < idx[str] && (idx[end] < idx[pend] || idx[end] > idx[str]))
				break;
			pend = end;
			end = (end == n - 1 ? 0 : end + 1);
		}
		int dif = end - str;
		if(end <= str)
			dif = end + n - str;
		mx = max(mx, dif);
	}
	cout << mx << endl;
	return 0;
}

/*
 * File: B.cpp
 * Author: wym510
 * Email: <wym6110@gmail.com>
 * Create Date: 2012-4-8 23:33:01
*/

#include <vector>
#include <string>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define S size()
#define B begin()
#define E end()
#define P push_back
#define fu(i,a,b) for(int i=a;i<b;++i)
#define fd(i,a,b) for(int i=b-1;i>=a;--i)
typedef long long int64;
using namespace std;

const int MaxN=3200000;
const int MaxM=3200000;
const int MaxNum=3200000;

int va[MaxN],vb[MaxM];
int pos[MaxNum];
int q[MaxN*2];

int main()
{
    int n,m;

    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",va+i);
    for(int i=1;i<=n;i++) va[i+n]=va[i];
    for(int i=1;i<=m;i++)
    {
        scanf("%d",vb+i);
        pos[vb[i]]=i;
    }

    int ans=0,ff=0,rr=0;

    for(int i=1,j=1;i<=2*n;i++)
    {
        while(j<i+n && j<=2*n)
        {
            if(pos[va[j]]==0) break;

            int kk=pos[va[j]];

            if(ff==rr) q[rr++]=kk;
            else
            {
                kk+=(q[rr-1]/m)*m;
                if(q[rr-1]>=kk) kk+=m;
                if(kk-q[ff]>=m) break;
                q[rr++]=kk;
            }
            j++;
        }
        ans=max(ans,j-i);
        if(ff<rr) ff++;
        if(i==j) j++;
    }

    cout<<ans<<endl;
    return 0;
}

/* vim: set ts=4 sw=4: */

/*
	Author : ChnLich
*/
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<sstream>
#include<fstream>
#include<algorithm>
#include<vector>
#include<list>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<string>
#include<bitset>
#include<functional>
#include<utility>

using namespace std;

typedef long long llint;
typedef pair<int,int> ipair;
#define fi first
#define se second
#define mp make_pair

void read(int &k)
{
	k=0; char x=getchar();
	while(x<'0'||x>'9') x=getchar();
	while(x>='0'&&x<='9') { k=k*10-48+x; x=getchar(); }
}

int n,m,a[2000010],b[2000010],pos[2000010],last,lin[2000010],now,tot,ans;

int main()
{
	//freopen("B.in","r",stdin);

	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i+n]=a[i];
	for(int i=1;i<=m;i++) scanf("%d",&b[i]),b[i+m]=b[i],pos[b[i]]=i;
	last=0;
	for(int i=1;i<=n;i++)
	{
		if (i>last&&pos[a[i]])
		{
			lin[i]=now=pos[a[i]]; tot=1; last=i;
			for(int j=i+1;j<i+n;j++) if (pos[a[j]])
			{
				if (pos[a[j]]>now) now=pos[a[j]];
				else if (pos[a[j]]<pos[a[i]]&&pos[a[j]]+m>now) now=pos[a[j]]+m;
				else break;
				lin[j]=now; tot++; last=j;
			} else break;
			if (tot>ans) ans=tot;
		} else if (pos[a[i]])
		{
			if (lin[i]>m)
				for(int j=i;j<=last;j++) lin[j]-=m;
			tot--; now=lin[last];
			for(int j=last+1;j<i+n;j++) if (pos[a[j]])
			{
				if (pos[a[j]]>now) now=pos[a[j]];
				else if (pos[a[j]]<pos[a[i]]&&pos[a[j]]+m>now) now=pos[a[j]]+m;
				else break;
				lin[j]=now; tot++; last=j;
			} else break;
			if (tot>ans) ans=tot;
		}
	}
	printf("%d\n",ans);

	return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <utility>
#include <math.h>
#include <cstdlib>
#include <memory.h>
#include <queue>

#define pb push_back
#define i64 long long
#define mp make_pair
#define pii pair <int,int>
#define vi vector <int>
#define vii vector <pii>
#define f first
#define s second
#define foran(i,a,b) for (int i=a;i<(int)b;i++)
#define forn(i,n) for (int i=0;i<(int)n;i++)
#define ford(i,n) for (int i=(int)n-1;i>=0;i--)

const double eps = 1e-9;
const int int_inf = 2000000000;
const i64 i64_inf = 1000000000000000000LL;
const double pi = acos(-1.0);

using namespace std;
int wa[1000010];
int wb[1000010];
int a[1000100];
int b[1000100];
int la,lb;
int res = 0;

int main() {
  memset(wa,-1,sizeof(wa));
  memset(wb,-1,sizeof(wb));
  cin >> la >> lb;
  forn(i,la) scanf("%d",&a[i]), wa[a[i]] = i;
  forn(i,lb) scanf("%d",&b[i]), wb[b[i]] = i;

  int f = wb[a[0]],last = f,len = 1;

  if (f != -1)
  {
   foran(i,1,la)
   {
     if (wb[a[i]] == -1) break;
     if (f <= last)
         if (wb[a[i]] > last || wb[a[i]] < f) { last = wb[a[i]]; len++; continue; } else break;
      if (wb[a[i]] > last && wb[a[i]] < f) { last = wb[a[i]]; len++; continue; } else break;
   }
  } else len = 0;

  res = max(res,len);

  foran(i,1,la)
  {
    if (len == 0)
    {
        if (wb[a[i]] == -1) continue;
        f = last = wb[a[i]];
        len = 1;
    } else
    {
        len--;
        f = wb[a[i]];
        if (f == -1) { len = 0; continue; }
    }

    int j = (i + len) % la;

    while (j != i)
    {
        if (wb[a[j]] == -1) break;
        if (f <= last)
            if (wb[a[j]] > last || wb[a[j]] < f) { last = wb[a[j]]; len++; j = (j+1)%la; continue; } else break;
        if (wb[a[j]] > last && wb[a[j]] < f) { last = wb[a[j]]; len++; j = (j+1)%la; continue; } else break;
    }

    res = max(res,len);
  }

  cout << res << endl;
  return 0;
}

#include <cassert>
#include <complex>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <iterator>
#include <limits>
#include <numeric>
#include <sstream>
#include <utility>

#include <algorithm>
#include <bitset>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

#include <memory.h>
//#include "bigint.h"

using namespace std;

#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define init(st) memset(st, 0, sizeof(st))
#define Pi 3.141592653589793
#define ll long long

// String operations
template<class T>
void splitstr(const string &s, vector<T> &out) {
  istringstream in(s);
  out.clear();
  copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T>
T read_value(string s) {
  T result;
  istringstream sin(s);
  sin >> result;
  return result;
}

#define read_int(s) read_value<int>(s)
#define read_ll(s) read_value<ll>(s)
#define read_float(s) read_value<float>(s)
#define read_double(s) read_value<double>(s)

string read_line() {
  string ret_val;
  getline(std::cin, ret_val);
  return ret_val;
}

template<class T>
void init_array(T *arr, int size, T value) {
  for (int i = 0; i < size; i++)
    arr[i] = value;
}

// Arithmetic operations
template<class T>
inline T gcd(T a, T b) {
  return (!a) ? b : gcd(b % a, a);
}

template<class T>
inline T mod(T a, T p) {
  a %= p;
  return (a < 0) ? a + p : a;
}

template<class T>
inline int numbits(T n) {
  return (!n) ? 0 : 1 + numbits(n & (n - 1));
}

template<class T>
inline T inverse(T a, T m) {
  a = mod<T>(a,m);
  return (a==1) ? 1 : mod((1-m*inverse(m%a,a))/a,m);
}

template<class T>
inline bool is_prime(T a) {
  T lim = (T)sqrt((double)a);
  for (T i = 2; i <= T(lim+1E-9); i++)
    if (a % i == 0)
       return false;
  return true;
}

template<class T>
inline T power(T a, T p, T mod) {
  if (!p) return 1;
  T temp = power(a, p>>1, mod);
  temp = (temp * temp) % mod;
  if (p&1)
    temp = (temp * a) % mod;
  return temp;
}

void get_primes(int start, int end, vector<int> &vi) {
  bool *p = new bool[end + 1];
  init_array<bool>(p, end+1, 0); p[1] = 1;
  for (int i = 2; i <= end; i++) {
    if (!p[i]) {
      if (i >= start)
        vi.push_back(i);
      for (int j = 2*i; j <= end; j += i)
        p[j] = 1;
    }
  }
  delete [] p;
}

// Graph operations
bool dfs(int current, int final, int total, vector<int> &visited, vector< vector<bool> > &edges, bool flow) {
  if (current == final) return true;
  if (visited[current]) return false;
  visited[current] = true;
  for (int i = 0; i < total; i++)
    if (edges[current][i] && dfs(i, final, total, visited, edges, flow)) {
      if (flow) {
        edges[current][i] = false;
        edges[i][current] = true;
      }
      return true;
    }
  return false;
}

int flow(int in, int out, int total, vector< vector<bool> > &edges) {
  int result = 0;
  for (vector<int> visited(total, 0); dfs(in, out, total, visited, edges, true); ++result)
    visited = vector<int>(total, 0);
  return result;
}

// Disjoint datasets
void create_set(int x, int *P, int *rank) {
  P[x] = x;
  rank[x] = 0;
}

int find_set(int x, int *P) {
  if (x != P[x]) P[x] = find_set(P[x], P);
  return P[x];
}

bool merge_sets(int x, int y, int *P, int *rank) {
  int Px = find_set(x, P);
  int Py = find_set(y, P);
  if(Px == Py) return false;
  if (rank[Px] > rank[Py]) P[Py] = Px;
  else P[Px] = Py;
  if (rank[Px] == rank[Py]) rank[Py]++;
  return true;
}

// Binary tree operations
template <typename T>
int read_cum_freq(int index, T *tree) {
  int sum = 0;
  while (index) {
    sum += tree[index];
    index -= (index & -index);
  }
  return sum;
}

template <typename T>
void upd_freq(int index, int mxIndex, int value, T *tree) {
  while (index <= mxIndex) {
    tree[index] += value;
    index += (index & -index);
  }
}

template <typename T>
int read_freq(int index, T *tree) {
  return read_cum_freq(index, tree) - read_cum_freq(index-1, tree);
}

// String algos.
void build_failure_function(const string &str, int *temp_arr) {
  temp_arr[0] = temp_arr[1] = 0;
  for (int i = 2; i <= sz(str); i++) {
    temp_arr[i] = -1;
    for (int ind = temp_arr[i-1]; temp_arr[i] == -1; ind = temp_arr[ind]) {
      if (str[ind] == str[i-1]) {
        temp_arr[i] = ind + 1;
      } else if (ind == 0) {
        temp_arr[i] = 0;
      }
    }
  }
}

void KMP(const string &text, const string &pattern, int *res) {
  int *temp_arr = new int[sz(pattern) + 1];
  build_failure_function(pattern, temp_arr);
  int i = 0;
  int ind = 0;
  while (i < sz(text)) {
    if (text[i] == pattern[ind]) {
      res[i] = ++ind;
      if (res[i] == sz(pattern)) {
        ind = temp_arr[ind];
      }
      i++;
    } else if (ind == 0) {
      res[i++] = 0;
    } else {
      ind = temp_arr[ind];
    }
  }
  delete [] temp_arr;
}

template <typename T, int N>
struct matrix {
  T m[N][N];
  T md;

  matrix(T md, bool unary = false) {
    this->md = md;
    init(m);
    if (unary) {
      for (int i = 0; i < N; i++) {
        m[i][i] = 1;
      }
    }
  }

  matrix operator*(const matrix &that) const {
    matrix ret_val(md, false);
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        for (int k = 0; k < N; k++) {
          ret_val.m[i][j] += this->m[i][k] * that.m[k][j];
          ret_val.m[i][j] %= md;
        }
      }
    }
    return ret_val;
  }

  vector<T> operator*(const vector<T> &vec) const {
    vector<T> ret_val(vec.size(), 0);
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        ret_val[i] += m[i][j] * vec[j];
        ret_val[i] %= md;
      }
    }
    return ret_val;
  }

  matrix power(int power) const {
  	matrix temporary = *this;
  	matrix ret_val(md, true);
  	while (power) {
  		if (power & 1)
  			ret_val = ret_val * temporary;
  		temporary = temporary * temporary;
  		power >>= 1;
  	}
  	return ret_val;
  }
};

// Setup
void setup(int value, string name) {
  string name_in = name + ".in";
  string name_out = name + ".out";
  freopen(name_in.c_str(), "r", stdin);
  if (value) freopen(name_out.c_str(), "w", stdout);
}

int arr[2000000];
int pos[1000001];

void run() {
  int l1, l2; std::cin >> l1 >> l2;
  for(int i = 0; i < l1; ++i) {
    scanf("%d", &arr[i]);
  }
  for (int i = 0; i < l1; ++i) {
    arr[l1 + i] = arr[i];
  }
  memset(pos, -1, sizeof(pos));
  for(int i = 0; i < l2; ++i) {
    int a; scanf("%d", &a);
    pos[a] = i;
  }
  int res = 0;
  deque<int> q;
  for (int i = 0; i < 2*l1; ++i) {
    if (pos[arr[i]] == -1) {
      q.clear();
    } else {
      int np = pos[arr[i]];
      while (q.size() >= 2) {
        if (q[0] < q.back()) {
          if (q.back() < np)
            break;
          if (np < q[0])
            break;
          q.pop_front();
        } else {
          if (np > q.back() && np < q[0])
            break;
          q.pop_front();
        }
      }
      q.push_back(pos[arr[i]]);
    }
    res = max(res, (int)q.size());
    if (res == l1) {
      break;
    }
  }
  std::cout << res << std::endl;
}

int main() {
#ifdef LOCAL_HOST
    setup(0, "temp");
#endif
    run();
    return 0;
}

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <bitset>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <iostream>
#include <algorithm>
//#include <sys/time.h>
using namespace std;
#define li        long long int
#define rep(i,to) for(int i=0;i<((int)(to));++i)
#define pb        push_back
#define sz(v)     ((li)(v).size())
#define bit(n)    (1ll<<(li)(n))
#define all(vec)  (vec).begin(),(vec).end()
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define MP        make_pair
#define F         first
#define S         second

#define MAX 1005000
int pos[MAX];
int a[MAX*3];
int b[MAX];

int main(){
	memset(pos,-1,sizeof(pos));
	int n,m;
	int left=0,right=0;
	int res=0;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	for(int i=0;i<m;i++) scanf("%d",&b[i]);
	for(int i=0;i<n*2;i++) a[i+n]=a[i];
	for(int i=0;i<m;i++) pos[b[i]]=i;
	while(left<n){
		res=max(res,right-left);
		int L=left;
		int R=right;
		int R1=right - 1;
		if(n<=R) R-=n;
		if(n<=R1) R1-=n;
		if(R1<0) R1+=n;

		int next=pos[a[R]];
		int bef=pos[a[R1]];
		int last=pos[a[L]];
		if(next==-1){
			left=++right;
		}else{
			if(left==right){
				right++;
			}else{
				if(next<=bef) next+=m;
				if(last<=bef) last+=m;
				if(last<=next){
					left++;
				}else{
					right++;
				}
			}
		}
	}
	printf("%d\n",res);
}

/*
* Problem:
* Author: Leo Yu
* Time:
* State:
* Memo:
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
inline int   read()
{
	int x = 0;	char ch = getchar();	bool positive = 1;
	for (; ch < '0' || ch > '9'; ch = getchar())  if (ch == '-')  positive = 0;
	for (; ch >= '0' && ch <= '9'; ch = getchar())    x = x * 10 + ch - '0';
	return positive ? x : -x;
}
#define link Link
#define next Next

int N, M, a[2000006], pos[2000006];

bool	in_segment(int l, int r, int x)
{
	if (l <= r)	return x >= l && x <= r;
	return x >= l || x <= r;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif

	N = read(), M = read();
	for (int i = 1; i <= N; ++ i)	a[i] = a[i + N] = read();
	for (int j = 1; j <= M; ++ j)	pos[read()] = j;
	int l = 0, r = 0;
	int ans = 0;
	for (int i = 1, j = 1; i <= N; ++ i)	if (pos[a[i]])
	{
		l = pos[a[i]];
		if (j <= i)	j = i + 1, r = pos[a[i]];
		while (j < i + N && pos[a[j]] && !in_segment(l, r, pos[a[j]]))
			r = pos[a[j ++]];
		ans = max(ans, j - i);
	}
	cout << ans << endl;

	return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std ;
#define rep( i, j, k ) for( i = j ; i <= k ; ++i )
#define MaxL 1000015
#define LL long long

struct node
{
	int v, fr ;
}br[MaxL], ar[MaxL] ;
int La, Lb, ans, pre[MaxL << 1] ;
LL h[MaxL << 1] ;

inline bool cmp ( node a, node b )
{
	return ( a.v < b.v ) ;
}

int main()
{
	int i, j, l, r, mid ;

	scanf("%d%d",&La, &Lb) ;
	rep( i, 1, La )
	{
		scanf("%d", &ar[i].v) ;
		ar[i].fr = i ;
	}
	rep( i, 1, Lb )
	{
		scanf("%d", &br[i].v) ;
		br[i].fr = i ;
	}

	sort( br+1, br+1+Lb, cmp ) ;
	sort( ar+1, ar+1+La, cmp ) ;
	for( j = i = 1 ; i <= La ; ++i )
	{
		for( ; br[j].v < ar[i].v && j <= Lb ; ++j ) ;
		if( br[j].v == ar[i].v )
			h[ar[i].fr] = h[ar[i].fr+La] = br[j].fr ;
	}

	for( i = 2 ; i <= ( La << 1 ) ; ++i )
	{
		if( ! h[i] ) continue ;
		if( h[i] < h[i-1] )
			h[i] = h[i] + ( ( h[i-1] - h[i] ) / Lb + 1 ) * Lb ;
	}
	for( i = 2 ; i <= ( La << 1 ) ; ++i )
	{
		pre[i] = pre[i-1] ;
		if( h[i] > h[i-1] && h[i-1] ) ++pre[i] ;
	}

	for( i = 1 ; i <= La ; ++i ) // ö�����
	{
		if( !h[i] ) continue ;
		for( l = i, r = i + La - 1 ; l <= r ; ) // ������ ÿһ������ �� ���� ���һ�� - ��Сһ�� <= Lb
		{
			mid = ( l + r ) >> 1 ;
			if( pre[mid] - pre[i] == mid - i && h[mid] - h[i] < Lb )
				l = mid + 1 ;
			else
				r = mid - 1 ;
		}
		ans = max( ans, l-i ) ;
	}

	printf("%d\n",ans) ;
//	system("pause") ;
	return 0 ;
}

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <cassert>
#include <numeric>
#include <string>
#include <cstring>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long int int64;

const int N = (int)2e6 + 100;

int n, m;
int str1[N], str2[N];

int pos[N];

bool in_seg(int x, int l, int r)
{
	if (l < r)
		return l <= x && x < r;
	return x >= l || x < r;
}

int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
#endif

	scanf("%d%d", &n, &m);

	for (int i = 0; i < n; i++)
		scanf("%d", &str1[i]);
	for (int i = 0; i < n; i++)
		str1[n + i] = str1[i];

	for (int i = 0; i < m; i++)
		scanf("%d", &str2[i]);

	for (int i = 0; i < N; i++)
		pos[i] = -1;
	for (int i = 0; i < m; i++)
		pos[str2[i]] = i;

	int ans = 0;

	int r1 = 0;
	int l2 = -1;
	int r2 = -1;

	for (int l1 = 0; l1 < n; l1++)
	{
		//printf("l1 = %d r1 = %d l2 = %d r2 = %d\n", l1, r1, l2, r2);

		while (true)
		{
			int c = str1[r1];
			int p = pos[c];

			if (p == -1)
				break;

			if (l2 != -1 && in_seg(p, l2, r2))
				break;

			if (l2 == -1)
				l2 = p;

			r2 = (p + 1) % m;
			r1++;
		}

		//printf("l1 = %d r1 = %d l2 = %d r2 = %d\n", l1, r1, l2, r2);

		ans = max(ans, r1 - l1);

		if (l1 == r1)
		{
			r1++;
			continue;
		}

		if (l1 == r1 - 1)
		{
			l2 = -1;
			r2 = -1;
			continue;
		}

		int c = str1[l1 + 1];
		l2 = pos[c] % m;
	}

	printf("%d\n", ans);

	return 0;
}

#include <cstdio>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <sstream>
#include <cctype>
#include <cmath>
using namespace std;
typedef long long LL;
#define FOR(x, b, e) for (int x = (b); x <= (e); ++x)
#define FORD(x, b, e) for (int x = (b); x >= (e); --x)
#define REP(x, n) for (int x = 0; x < (n); ++x)
#define VAR(v, n) typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define SIZE(x) ((int) (x).size())
#define EACH(i, c) for (VAR(i, (c).begin()); i != (c).end(); ++i)
#define REACH(i, c) for (VAR(i,(c).rbegin()); i != (c).rend(); ++i)
#define UNIQUE(v) do { sort(ALL(v)); (v).resize(unique(ALL(v)) - (v).begin()); } while (0)
#define PB push_back
#define ST first
#define ND second
#define MP make_pair
#define skip continue
const int INF = 1000000001;

#define GET(x)			(scanf("%d", &(x)) == 1)
#define GET2(x, y)		(scanf("%d %d", &(x), &(y)) == 2)
#define GET3(x, y, z)	(scanf("%d %d %d", &(x), &(y), &(z)) == 3)
#define GETS(x)			(scanf("%s", (x)) == 1)
#define DGET(x)			int x; GET(x);

template<class T>
bool remax(T &a, const T &b) { return a < b ? (a = b, 1) : 0; }
template<class T>
bool remin(T &a, const T &b) { return a > b ? (a = b, 1) : 0; }

const int N = 1000001;
int A[2 * N], posB[N];

int main()
{
	int la, lb, x;
	GET2(la, lb);

	FOR (i, 1, la) {
		GET(A[i]);
		A[i + la] = A[i];
	}

	FOR (i, 1, lb) {
		GET(x);
		posB[x] = i;
	}

	int best = 0;
	int lastMatch = 0;

	FOR (start, 1, la) {
		int sb = posB[A[start]];
		if (!sb) {
			lastMatch = 0;
			skip;
		}

		remax(best, 1);

		remax(lastMatch, 0);

		int last = 0;
		int ini = start + max(1, lastMatch - 1);

		remin(ini, start + la - 1);

		int matched = ini - start;

		FOR (i, ini, start + la - 1) {
			int p = posB[A[i]];

			//~ remax(best, i - start - 1);
			if (!p) {
				lastMatch = 0;
				break;
			}

			p -= sb;
			if (p < 0) p += lb;

			if (!remax(last, p)) {
				lastMatch = i - start - 1;
				break;
			}
			++lastMatch;
			++matched;
		}

		remax(best, matched);
	}

	printf("%d\n", best);
}

#include <cstdio>
#include <deque>

int a[1000001];
int p[1000001];

int main() {
  int l, r, i, c, v; scanf("%d%d", &l, &r);
  for (i = 0; i < l; ++i) scanf("%d", &a[i]);
  for (i = 1; i <= r; ++i) scanf("%d", &c), p[c] = i;
  std::deque<int> q;
  for (i = r = 0; i < 2*l; ++i) {
    c = p[a[i%l]];
    if (c) {
      while (q.size() >= 2 && !(q[0] < v && (v < c || c < q[0]) || q[0] > v && v < c && c < q[0]))
        q.pop_front();
      q.push_back(v=c);
    } else q.clear();
    if (q.size() > r) r = q.size();
  }
  printf("%d", l<r?l:r);
}//hellobig_tq

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

// Template Begin(By yayamao)
#ifndef ONLINE_JUDGE
    #define READ freopen("in", "r", stdin)
    #define WRITE freopen("out", "w", stdout)
#else
    #define READ
    #define WRITE
#endif

#ifdef _MSC_VER
    #define int64 __int64
    #define uint64 unsigned __int64
#else
    #define int64 long long
    #define uint64 unsigned long long
#endif

#define EPS 1E-9
#define D_INF 1E99
#define I_INF 0x7FFFFFFF
#define L_INF 0x7FFFFFFFFFFFFFFFLL

#define S(x) ((int)x.size())
#define L(x) ((int)x.length())

#define VI vector<int>
#define VS vector<string>
#define PB(x) push_back(x)

#define MII map<int, int>
#define MSI map<string, int>
#define MIS map<int, string>

#define X first
#define Y second
#define PII pair<int, int>
#define PSI pair<string, int>
#define PIS pair<int, string>
#define MP(x,y) make_pair(x, y)

#define TWO(x)			(1 << (x))
#define TWOL(x)			(1int64 << (x))
#define LOWER_BIT(x)	((x) & (-(x)))
#define CONTAIN(s,x)	(((s) & TWO(x)) != 0)
#define CONTAINL(s,x)	(((s) & TWOL(x)) != 0)

template<class T>inline void checkMax(T &a, const T &b){if (a < b) a = b;}
template<class T>inline void checkMin(T &a, const T &b){if (b < a) a = b;}
template<class T>inline std::string toString(const T &n){std::ostringstream out;out << n;out.flush();return out.str();}
template<class T>inline T toValue(const std::string &s){T x;std::istringstream in(s);in >> x;return x;}
bool hasNext(){char c;if (scanf(" %c", &c) == EOF) return false;ungetc(c, stdin);return true;}

int dx[]={ 0, 0,-1, 1,-1, 1,-1, 1};
int dy[]={-1, 1, 0, 0,-1,-1, 1, 1};
std::string dir[]={"L", "R", "U", "D", "LU", "LD", "RU", "RD"};

int tenPower[10]={0x1, 0xA, 0x64, 0x3E8, 0x2710, 0x186A0, 0xF4240, 0x989680, 0x5F5E100, 0x3B9ACA00};

#define setv(a, v) memset(a, v, sizeof(a))

// [l, r]
#define range(i, l, r) for(int i = (l); i <= (int)(r); ++i)
#define rangeD(i, r, l) for(int i = (r); i >= (int)(l); --i)

// [0,n)
#define rep(i, n) for(int i = 0; i< (int)(n); ++i)
#define repD(i, n) for(int i = (int)(n) - 1;i >= 0; --i)

#define all(c) (c).begin(), (c).end()
#define foreach(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
// Template Ended(By yayamao)

const int N = 1000000 + 128;

int aL, a[N], posA[N];
int bL, b[N], posB[N];

void read() {
    setv(posA, -1);
    setv(posB, -1);

    cin >> aL >> bL;
    rep (i, aL) {
        scanf("%d", &a[i]);
        posA[a[i]] = i;
    }
    rep (i, bL) {
        scanf("%d", &b[i]);
        posB[b[i]] = i;
    }
}

bool ok(int l, int r, int r1) {
    if (-1 == r1) {
        return false;
    }
    if (r >= l) {
        return r1 > r || r1 < l;
    } else {
        return r1 > r && r1 < l;
    }
}

int getLength(int l, int r) {
    if (r >= l) {
        return r - l + 1;
    } else {
        return r - l + 1 + aL;
    }
}

int solve() {
    int maxL = 0;
    for (int l = 0, r = -1; l < aL; ++l) {
        if (-1 == posB[a[l]]) {
            continue;
        }
        if (r == -1) {
            r = l;
        }
        while ((r + 1) % aL != l && ok(posB[a[l]], posB[a[r]], posB[a[(r + 1) % aL]])) {
            r = (r + 1) % aL;
        }
        checkMax(maxL, getLength(l, r));
        if (r == l) {
            r = -1;
        }
    }
    return maxL;
}
void run(const int caseID) {
    read();

    cout << solve() << endl;
}

void runWithCaseT() {
    int caseT;
    scanf("%d", &caseT);
    for(int caseID = 1; caseID <= caseT; ++caseID) {
        run(caseID);
    }
}

void runWithoutCaseT() {
    int caseID = 0;
    while(hasNext()) {
        run(++caseID);
    }
}

int main(int argc, char *argv[]) {
    READ;
    //WRITE;

    //runWithCaseT();
    runWithoutCaseT();

    return (EXIT_SUCCESS);
}

#include<cmath>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<sstream>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<time.h>
#include<stdlib.h>
#include<assert.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define rep(i,l,r) for(int i=(l);i<(r);++i)
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e6 + 7;
const int INF = 1e9 + 7;
const int MOD = 1e9 + 7;
const double Pi = acos(-1.0);
const double EPS = 1e-8;
//--------head--------
int n, m, a[N << 1], R[N];
int h[2], t[2], que[N << 1];
int main() {
	scanf("%d%d", &n, &m);
	rep(i, 0, n)
		scanf("%d", a + i);
	memset(R, -1, sizeof(R));
	rep(i, 0, m) {
		int x;
		scanf("%d", &x);
		R[x] = i;
	}
	rep(i, 0, n)
		a[i] = a[n + i] = R[a[i]];
	a[n << 1] = -1;
	//	rep(i, 0, 2 * n) printf("%d ", a[i]);puts("");
	int ans = 0;
	for (int i = 0; i < n; ++i) {
		if (a[i] == -1)
			continue;
		ans = max(ans, 1);
		int j, w = 0;
		h[0] = t[0] = 0, h[1] = t[1] = n;
		que[t[0]++] = a[i];
		for (j = i + 1; ~a[j] && j < (n << 1); ++j) {
			if (a[j] < que[t[w] - 1]) {
				if (w == 1) {
					swap(h[0], h[1]), swap(t[0], t[1]);
					h[1] = t[1] = (h[0] >= n ? 0 : n);
				}
				w = 1;
			}
			if (w == 1)
				while (h[0] < t[0] && que[h[0]] <= a[j])
					++h[0];
			que[t[w]++] = a[j];
			ans = max(ans, (t[0] - h[0]) + (t[1] - h[1]));
		}
		i = j;
	}
	printf("%d", ans);
	return 0;
}

#include <cstdio>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <sstream>
#include <cctype>
#include <cmath>
using namespace std;
typedef long long LL;
#define FOR(x, b, e) for (int x = (b); x <= (e); ++x)
#define FORD(x, b, e) for (int x = (b); x >= (e); --x)
#define REP(x, n) for (int x = 0; x < (n); ++x)
#define VAR(v, n) typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define SIZE(x) ((int) (x).size())
#define EACH(i, c) for (VAR(i, (c).begin()); i != (c).end(); ++i)
#define REACH(i, c) for (VAR(i,(c).rbegin()); i != (c).rend(); ++i)
#define UNIQUE(v) do { sort(ALL(v)); (v).resize(unique(ALL(v)) - (v).begin()); } while (0)
#define PB push_back
#define ST first
#define ND second
#define MP make_pair
#define skip continue
const int INF = 1000000001;

#define GET(x)			(scanf("%d", &(x)) == 1)
#define GET2(x, y)		(scanf("%d %d", &(x), &(y)) == 2)
#define GET3(x, y, z)	(scanf("%d %d %d", &(x), &(y), &(z)) == 3)
#define GETS(x)			(scanf("%s", (x)) == 1)
#define DGET(x)			int x; GET(x);

template<class T>
bool remax(T &a, const T &b) { return a < b ? (a = b, 1) : 0; }
template<class T>
bool remin(T &a, const T &b) { return a > b ? (a = b, 1) : 0; }

const int N = 1000001;
int A[2 * N], posB[N];

int main()
{
	int la, lb, x;
	GET2(la, lb);

	FOR (i, 1, la) {
		GET(A[i]);
		A[i + la] = A[i];
	}

	FOR (i, 1, lb) {
		GET(x);
		posB[x] = i;
	}

	int best = 0;
	int lastMatch = 0;

	FOR (start, 1, la) {
		int sb = posB[A[start]];
		if (!sb) {
			lastMatch = 0;
			skip;
		}

		remax(lastMatch, 0);

		int last = 0;
		int ini = start + max(1, lastMatch - 1);

		remin(ini, start + la - 1);

		int matched = ini - start;

		FOR (i, ini, start + la - 1) {
			int p = posB[A[i]];

			//~ remax(best, i - start - 1);
			if (!p) {
				lastMatch = 0;
				break;
			}

			p -= sb;
			if (p < 0) p += lb;

			if (!remax(last, p)) {
				lastMatch = i - start - 1;
				break;
			}
			++lastMatch;
			++matched;
		}

		remax(best, matched);
	}

	printf("%d\n", best);
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.14159265358979
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

using namespace std;
int is[1000010][2];
int a[2000010];
int b[2000010];
int dp[2000010][2];
int with[2000010][2];
int main()
{
	//freopen("in.txt","r",stdin);
	int n,m;
	scanf("%d%d",&n,&m);
	MEMS(is,-1);
	FOR(i,0,n)
	{
		scanf("%d",&a[i]);
		a[n+i]=a[i];
	}
	FOR(i,0,m)
	{
		scanf("%d",&b[i]);
		b[m+i]=b[i];
		is[b[i]][0]=i;
		is[b[i]][1]=m+i;
	}
	int res=0;
	int last=0;
	if (is[a[0]][0]!=-1)
	{
		dp[0][0]=1;
		dp[0][1]=1;
		with[0][0]=with[0][1]=is[a[0]][0];
	}
	else
	{
		with[0][0]=with[0][1]=-1;
		last=1;
	}
	res=max(res,dp[0][0]);
	res=max(res,dp[0][1]);
	FOR(i,1,2*n)
	{
		if (is[a[i]][0]==-1)
		{
			with[0][0]=with[0][1]=-1;
			last=i+1;
		}
		else
		{
			if (is[a[i]][0]>with[i-1][0])
			{
				with[i][0]=is[a[i]][0];
				while (is[a[i]][0]-with[last][0]>=m)
					last++;
				dp[i][0]=i-last+1;
			}
			else
			{
				if (is[a[i]][1]>with[i-1][0])
				{
					with[i][0]=is[a[i]][1];
					while (is[a[i]][1]-with[last][0]>=m)
						last++;
					dp[i][0]=i-last+1;
				}
				else
				{
					dp[i][0]=1;
					last=i;
					with[i][0]=is[a[i]][0];
				}
			}
			dp[i][1]=1;
			with[i][1]=is[a[i]][0];
		}
		res=max(res,dp[i][0]);
		res=max(res,dp[i][1]);
	}
	int v=min(n,m);
	if (res>v)
		res=v;
	cout<<res<<endl;
	return 0;
}

#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <deque>
#include <iostream>
#include <iomanip>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <string> vs;

#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define REP(i, a) for (int i = 0; i < (a); i++)
#define REPD(i, a) for (int i = ((a) - 1); i >= 0; i--)
#define FIT(it, v) for (typeof((v).begin())it = (v).begin(); it != (v).end(); ++it)
#define FITD(it, v) for (typeof((v).rbegin())it = (v).rbegin(); it != (v).rend(); ++it)

#define VAR(a, b) typeof(b) a(b)
#define ALL(v) (v).begin(), (v).end()
#define SET(a, x) memset((a), (x), sizeof(a))
#define SIZE(a) ((int)(a).size())

#define EXIST(a, b) (find(ALL(a), (b)) != (a).end())
#define SORT(x) sort(ALL(x))
#define GSORT(x) sort(ALL(x), greater<typeof(*((x).begin()))>())
#define UNIQUE(v) SORT(v); (v).resize(unique(ALL(v)) - (v).begin())
#define ENUM(v) FIT(it, (v)) cout << *it << " "; cout << endl

#define PF push_front
#define PB push_back
#define MP make_pair
#define F first
#define S second

const char IN[] = "_.in";
const char OUT[] = "_.out";
const int maxn=2010000;

int ntest = 0, test;
int n,m,res,l,r;
int a[maxn],b[maxn],vt[maxn];
void nhap()
{
    cin>>n>>m;
    FOR(i,1,n) cin>>a[i];
    FOR(j,1,m) cin>>b[j];

}

void init()
{

    FOR(i,n+1,n*2)
    {
        a[i]=a[i-n];
        vt[a[i]]=-1;
    }
    vt[0]=-1;
    FOR(i,1,m)
    vt[b[i]]=i;
}

bool ok(int l,int r,int u)
{

    if (l<=r)
    {
        if (l<=u && u<=r) return 0; else return 1;
    }
    else
    {
        if (r<u && u<l) return 1; else return 0;
    }
    return 0;
}
void solve()
{
    res=0;
    l=1;
    r=0;

    while (r<=2*n)
    {
        if (vt[a[r+1]]!=-1 && ok(vt[a[l]],vt[a[r]],vt[a[r+1]]) && r+1<=n*2 )
        r++;
        else
        {
            res=max(res,r-l+1);
            while (vt[a[l+1]]==-1 && l+1<=n) l++;
            l++;
            if (l>n) break;
            if (r<l) r=l;

        }
    }

    cout<<res;

}
int main() {
  //  freopen(IN, "r", stdin);
  //freopen(OUT, "w", stdout);
  ios_base::sync_with_stdio(false);
    nhap();
    init();
    solve();
    return 0;
}

/* Writen by Filip Hlasek 2012 */
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstring>

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,b) for(int i=0;i<b;i++)

using namespace std;

#define MAXN 1111111
int a[2*MAXN],b[MAXN],A,B;
int pos[MAXN];

int main(int argc, char *argv[]){
  REP(i,MAXN) pos[i] = -1;
  scanf("%d%d",&A,&B);
  REP(i,A){
    scanf("%d",a+i);
    a[A+i] = a[i];
  }
  REP(i,B) scanf("%d",b+i);
  REP(i,B) pos[b[i]] = i;
  int start = 0, end = 0, best = 0;
  while(start < A && pos[a[start]] == -1) start++;
  if(start == A){ printf("0\n"); return 0; }
  end = start;
  bool over = false;
  while(start < A){
    //printf("start:%d end:%d over:%d - next:%d pos-start:%d\n",start,end,(int)over,pos[a[end+1]],pos[start]);
    while(true){
      if(pos[a[end+1]] == -1) break;
      if(pos[a[end+1]] > pos[a[end]]){ end++; continue; }
      if(!over && pos[a[end+1]] < pos[a[start]]){
        over = true;
        end++;
      }
      else break;
    }
    /*
    while(pos[a[end+1]] != -1 && ((!over && (pos[a[end+1]] > pos[a[end]] || pos[a[end+1]] < pos[a[start]])) ||
                                            (pos[a[end+1]] > pos[a[end]] && pos[a[end+1]] < pos[a[start]]))){
      if(pos[a[end+1]] <= pos[a[end]]) over = true;
      end++;
    }
    */
    //printf("...start:%d end:%d over:%d\n",start,end,(int)over);
    best = max(best, end - start + 1);
    start++;
    if(end < start){
      over = false;
      while(start < A && pos[a[start]] == -1) start++;
      end = start;
    }
  }
  printf("%d\n",best);
  return 0;
}

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <stdio.h>

using namespace std;

#define fo(i,n) for(int i=0; i<(int)n; i++)
#define rep(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
#define mp(a,b) make_pair(a,b)
#define pb(x) push_back(x)
#define pii pair<int,int>

int n,m;
int v1[1000005];
int v2[1000005];
int id[1000005];
int w[1000005];

int main() {

    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    scanf("%d%d",&n,&m);
    for (int i=0; i<n; i++) scanf("%d",v1+i);
    for (int i=0; i<m; i++) scanf("%d",v2+i);

    for (int i=0; i<1000005; i++) id[i] = -1;
    for (int i=0; i<m; i++) id[v2[i]] = i;

    for (int i=0; i<2*n; i++) w[i] = id[v1[i%n]];

    int minimo = -1;
    int c = 0;
    int last = -1;
    int res = 0;

    for (int i=0; i<2*n-1; i++) {

        if (last==-1) {
            if (w[i]==-1);
            else if (w[i]!=-1 && w[i+1]==-1) {
                res = max(res,1);
            }
            else if (w[i]<w[i+1]) {
                minimo = w[i];
                c = 1;
                last = w[i+1];
            }
            else if (w[i]<w[i+1]+m) {
                minimo = w[i];
                c = 1;
                last = w[i+1]+m;
            }
        }
        else {
            if (w[i+1]==-1 || last > w[i+1]+m || (w[i+1]+m>last && w[i+1]+m-minimo>=m) ) {
                res = max(res,c+1);
                last = -1;
                i--;
            }
            else {
                if (last < w[i+1]) {
                    c++;
                    last = w[i+1];
                }
                else {
                    c++;
                    last = w[i+1]+m;
                }
            }
        }
        //cout<<i<<" "<<last<<" "<<w[i]<<" "<<w[i+1]<<" "<<minimo<<endl;
        //cout<<res<<endl;
    }

    cout<<res<<endl;

    return 0;

}

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
using namespace std;

int m1[2000005];
int m2[2000005];
int pos1[1000005];
int pos2[1000005];
int ans[2000005];
int parent[2000005];
int n1, n2;

int main()
{
//  memset(ans, -1, sizeof(ans));
    scanf("%d%d", &n1, &n2);
    int i;
    for(i = 1; i <= n1; i++)
    {
        scanf("%d", m1 + i);
        m1[n1 + i] = m1[i];
        pos1[m1[i]] = i;
    }
    for(i = 1; i <= n2; i++)
    {
        scanf("%d", m2 + i);
        m2[n2 + i] = m2[i];
        pos2[m2[i]] = i;
    }
    int res = 0;
    int st = 1;
    for(i = 1; i <= n1 + n1; i++)
    {
        int p2 = pos2[m1[i]];
        int t = 0;
        if(p2)
        {
            if(ans[i - 1])
            {
                p2 += (parent[i - 1] - 1) / n2 * n2;
                if(parent[i - 1] > p2)
                {
                    p2 += n2;
                }
                while(st < i && p2 - parent[st] + 1 > n2) st++;
                t = i - st + 1;
                parent[i] = p2;
            }
            else
            {
                t = 1;
                st = i;
                parent[i] = p2;
            }
        }
//      cout << i << ' ' << st << ' ' << parent[i] << endl;
        ans[i] = t;
//      cout << ans[i] << ' ' << parent[i] << endl;
        if(ans[i] > res) res = ans[i];
    }
    printf("%d\n", res);
    return 0;
}

#include<stdio.h>
#include<algorithm>
using namespace std;

int a[2000005],pos[1000005];
bool in_subseq(int x,int l,int r)
{
    if(l<=r) return l<=x && x<=r;
    return (r<=x || x<=l);
}

int main()
{
    int m,n,i,j,ans=0;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;++i)
    {
        scanf("%d",&a[i]);
        a[i+m]=a[i];
    }
    for(i=1;i<=n;++i)
    {
        scanf("%d",&j);
        pos[j]=i;
    }
    for(i=1,j=2;i<=m;++i) if(pos[a[i]])
    {
        if(j<=i) j=i+1;
        while(j<i+m && pos[a[j]] && !in_subseq(pos[a[j]],pos[a[i]],pos[a[j-1]])) ++j;
        ans=max(ans,j-i);
    }
    printf("%d",ans);
}

#include<stdio.h>
#include<algorithm>
using namespace std;

int a[2000005],pos[1000005]={0};
bool in_subseq(int x,int l,int r)
{
    if(l<=r) return (l<x && x<r);
    return (r<x || x<l);
}

int main()
{
    int m,n,i,j,ans=0;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;++i)
    {
        scanf("%d",&a[i]);
        a[i+m]=a[i];
    }
    for(i=1;i<=n;++i)
    {
        scanf("%d",&j);
        pos[j]=i;
    }
    for(i=1,j=1;i<=m;++i) if(pos[a[i]])
    {
        if(j<=i) j=i+1;
        while(j<i+m && pos[a[j]] && !in_subseq(pos[a[j]],pos[a[i]],pos[a[j-1]])) ++j;
        ans=max(ans,j-i);
    }
    printf("%d",ans);
}

#include <cstdio>
#include <numeric>
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <queue>
#include <sstream>
#include <deque>

using namespace std;

#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0; i < (n); i++)
#define re return
#define fi first
#define se second
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(abs(x))
#define y0 y3487465
#define y1 y8687969
#define fill(x,y) memset(x,y,sizeof(x))

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef double D;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<vi> vvi;

template<class T> T abs(T x) { re x > 0 ? x : -x; }

int n;
int m;
int x[2000000], f[1000000];

int get (int a, int b) {
    if (a > b) b += m;
    re b - a;
}

int main () {
    scanf ("%d%d", &n, &m);
    for (int i = 0; i < 1000000; i++) f[i] = -1;
    for (int i = 0; i < n; i++) {
        scanf ("%d", &x[i]); x[i]--;
        x[n + i] = x[i];
    }
    for (int i = 0; i < m; i++) {
        int y;
        scanf ("%d", &y); y--;
        f[y] = i;
    }
    int l = 0, r = -1, y = -1, len = 0, cnt = 0;
    int ans = 0;
    while (r + 1 < 2 * n) {
        r++;
        if (f[x[r]] == -1) {
            l++;
            y = -1;
            len = 0;
            cnt = 0;
        } else {
            if (y == -1) {
                y = f[x[r]];
                len = 0;
                cnt = 1;
            } else {
                len += get (y, f[x[r]]);
                y = f[x[r]];
                cnt++;
                while (len >= m) {
                    len -= get (f[x[l]], f[x[l + 1]]);
                    cnt--;
                    l++;
                }
            }
        }
        ans = max (ans, cnt);
    }
    printf ("%d\n", min (ans, n));
    return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;

const int maxn = 1000002;
int a[maxn*2], b[maxn*2], v[maxn][2];

int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n, m;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; ++i)
		scanf("%d", &a[i]), a[i + n] = a[i];
	for(int i = 0; i < m; ++i)
		scanf("%d", &b[i]), b[i + m] = b[i];
	for(int i = 0; i < maxn; ++i)
		v[i][0] = v[i][1] = -1;
	for(int i = 0; i < m; ++i)
		v[b[i]][0] = i, v[b[i+m]][1] = i + m;
	int p = 0, t = 0, ans = 0;
	for(int i = 0; i < n; ++i)
	{
		if(p <= i) p = i, t = 0;
		while(p + 1 < 2*n && v[a[p+1]][t] > v[a[p]][t] && v[a[p+1]][t] - v[a[i]][0] + 1 <= m)
			++p;
		while(p + 1 < 2*n && v[a[p+1]][1] > v[a[p]][t] && v[a[p+1]][1] - v[a[i]][0] + 1 <= m)
			++p, t = 1;
		if(v[a[i]][0] != -1)
			ans = max(ans, p - i + 1);
	}
	cout << ans;

	return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>

using namespace std;

#define FOREACH(i, c) for(__typeof( (c).begin() ) i = (c).begin(); i != (c).end(); ++i)
#define FOR(i, a, n) for(__typeof(n) i = (a); i<(n); ++i)
#define REP(i, n, a) for(__typeof(n) i = (n); i>=(a); --i)
#define error(n) cout << #n << " = " << n << endl
#define all(c) c.begin(), c.end()
#define pb push_back
#define po pop_back
#define Size(n) ((int)(n).size())
#define pii pair<int, int>
#define X first
#define Y second
// #define X real()
// #define Y imag()

typedef long long   ll ;
typedef long double ld ;

const int MAXN = 1000 * 1000 + 10 ;

int N , M ;
int a[2*MAXN] ;
int pos[MAXN] ;

bool OK (int a , int b , int c) {
    if (c < a)
        return ((a<b)||(b<c)) ;
    else
        return ((a<b)&&(b<c)) ;
}

int main() {
    scanf ("%d %d" , &N,&M) ;
    FOR (i,0,N) {
        scanf ("%d" , &a[i]) ;
        a[N+i] = a[i] ;
    }
    FOR (i,0,M) {
        int tmp ;
        scanf ("%d" , &tmp) ;
        pos[tmp] = i ;
    }
    int ans = 0 ;
    for (int i = 0 , j = 0 ; i < N ; ++i) {
        for (j = max(i,j) ; j < i+N && pos[a[j]] != -1 ; ++j) {
            if (j <= i+1) continue ;
            if (!OK(pos[a[i]] , pos[a[j-1]] , pos[a[j]])) break ;
        }
        ans = max(ans,j-i) ;
    }
    cout << ans << endl ;
    return 0 ;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
using namespace std;

int m1[2000005];
int m2[2000005];
int pos1[1000005];
int pos2[1000005];
int ans[2000005];
int parent[2000005];
int n1, n2;

int main()
{
//  memset(ans, -1, sizeof(ans));
    scanf("%d%d", &n1, &n2);
    int i;
    for(i = 1; i <= n1; i++)
    {
        scanf("%d", m1 + i);
        m1[n1 + i] = m1[i];
        pos1[m1[i]] = i;
    }
    for(i = 1; i <= n2; i++)
    {
        scanf("%d", m2 + i);
        m2[n2 + i] = m2[i];
        pos2[m2[i]] = i;
    }
    int res = 0;
    int st = 1;
    for(i = 1; i <= n1 + n1; i++)
    {
        int p2 = pos2[m1[i]];
        int t = 0;
        if(p2)
        {
            if(ans[i - 1])
            {
                p2 += (parent[i - 1] - 1) / n2 * n2;
/*              while(parent[i - 1] > p2)
                {
                    p2 += n2;
                }*/
                while(st < i && p2 - parent[st] + 1 > n2) st++;
                t = i - st + 1;
                parent[i] = p2;
            }
            else
            {
                t = 1;
                st = i;
                parent[i] = p2;
            }
        }
//      cout << i << ' ' << st << ' ' << parent[i] << endl;
        ans[i] = t;
//      cout << ans[i] << ' ' << parent[i] << endl;
        if(ans[i] > res) res = ans[i];
    }
    printf("%d\n", res);
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

#define k6 1000006

int la, lb;

int cod[k6];
int fun=0;

int b[k6];

int ml[k6];

int pos[k6];

int main()
{
	memset(cod, 0xff, sizeof(cod));
	scanf("%d %d", &la, &lb);
	for(int i=0;i<la; i++)
	{
		int t;
		scanf("%d",&t);
		cod[t] = i;
	//	a[i]=i;//a[la+i]=i;
		//a[la+i]=a[i];
	}

	memset(pos, 0xff, sizeof(pos));
	int lb2 = 0;
	for(int i=0;i<lb; i++)
	{
		int t;
		scanf("%d",&t);
		if(cod[t]!=-1){
			b[lb2++]=cod[t];
			pos[cod[t]] = lb2-1;
		}
	}

	int ans = 0;

	queue<long long> Q;
	queue<long long> q1;
	queue<long long> q2;
	long long pz=0;
	int prpos = -1;
	int sl = -1;
	for(int i=0; i<la;i++)
	{
		if(pos[i]==-1){
			if(sl==-1){
				sl = 1;
				while(!Q.empty()){
					q1.push(Q.front());
					Q.pop();
				}
			}
			while(!Q.empty())Q.pop();
			pz = 0;
			prpos=-1;
		}else{
			long long cpos = pos[i] + pz;
			if(pos[i]<prpos){
				pz+=lb2;
				cpos+=lb2;
			}
			while(!Q.empty() && cpos-Q.front()>=lb2 ){
				Q.pop();
			}
			Q.push(cpos);
			prpos = pos[i];
		}
		ans = max(ans, (int)Q.size());
	}

	if(!Q.empty() && !q1.empty())
	{
		while(!q1.empty())
		{
			long long cpos = q1.front()+pz;
			q1.pop();
			while(!Q.empty() && cpos-Q.front()>=lb2)
				Q.pop();
			Q.push(cpos);
			if(Q.size() > ans) ans = Q.size();
		}
	}

	for(int i=0;i<la;i++)ans = max(ans, ml[i]);
	printf("%d\n",ans);

	return 0;
}

//#define BITSET64BIT 1
#ifdef BITSET64BIT
#include <string>
#include <bits/functexcept.h>
#include <iosfwd>
#include <bits/cxxabi_forced.h>
#include <bits/functional_hash.h>

#pragma push_macro("__SIZEOF_LONG__")
#pragma push_macro("__cplusplus")
#define __SIZEOF_LONG__ __SIZEOF_LONG_LONG__
#define unsigned unsigned long
#define __cplusplus 201102L

#define __builtin_popcountl __builtin_popcountll
#define __builtin_ctzl __builtin_ctzll

#include <bitset>

#pragma pop_macro("__cplusplus")
#pragma pop_macro("__SIZEOF_LONG__")
#undef unsigned
#undef __builtin_popcountl
#undef __builtin_ctzl
#endif

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

// Optimization

/*
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma comment(linker,"/stack:200000000")
*/
#define endl '\n'

// Shortcut

#define int long long
#define eb emplace_back
#define pb push_back
#define pob pop_back
#define upb upper_bound
#define lwb lower_bound
#define fi first
#define se second
#define For(i, l, r) for (int i = l; i < r; i++)
#define ForE(i, l, r) for (int i = l; i <= r; i++)
#define Ford(i, r, l) for (int i = r; i > l; i--)
#define FordE(i, r, l) for (int i = r; i >= l; i--)
#define Fora(i, a) for (auto i : a)

// I/O & Debug

#define PrintV(a) Fora(h13, a) cout << h13 << ' '; cout << endl;
#define PrintVl(a) Fora(h13, a) cout << h13 << endl;
#define PrintA(a, l, r) for (int h13 = l; h13 <= r; h13++) cout << a[h13] << ' '; cout << endl;
#define PrintAl(a, l, r) for (int h13 = l; h13 <= r; h13++) cout << a[h13] << endl;
#define Ptest(x) return cout << x, 0;
#define getl(s) getline(cin, s);
#define setpre(x) fixed << setprecision(x)
/*
#define debug(args...){                                                                     \\
    string _sDEB = #args;                                                                   \\
    replace(_sDEB.begin(), _sDEB.end(), ',', ' ');                                          \\
    stringstream _ssDEB(_sDEB);                                                             \\
    istream_iterator<string> _itDEB(_ssDEB);                                                \\
    DEB(_itDEB, args);                                                                      \\
}
void DEB(istream_iterator<string> it) {}
template<typename T, typename... Args>
void DEB(istream_iterator<string> it, T a, Args... args){
    cout << *it << " = " << a << endl;
    DEB(++it, args...);
}
*/

// Functions

//#define isvowel(a) (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
#define bend(a) a.begin(), a.end()
#define rbend(a) a.rbegin(), a.rend()
#define mset(a) memset(a, 0, sizeof(a))
#define mset1(a) memset(a, 1, sizeof(a))
#define msetn1(a) memset(a, -1, sizeof(a))
#define msetinf(a) memset(a, 0x3f, sizeof(a))
#define gcd __gcd
#define __builtin_popcount __builtin_popcountll
//mt19937 rando(chrono::steady_clock::now().time_since_epoch().count());
//int randt(int l, int r){ return (rando() % (r - l + 1) + l); }

// Data Structure

// Policy based data structures                                                             \\
   Support find_by_order(int k): return an iterator to the k-th smallest element,           \\
                                 counting from 0                                            \\
           order_of_key(int k): return the number of items strictly smaller than k          \\
   For ordered_multiset and ordered_multimap, lower_bound() and upper_bound() are swapped

template <typename T> using ordered_set =
tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename Key, typename T> using ordered_map =
tree <Key, T, less <Key>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =
tree <T, null_type, less_equal <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename Key, typename T> using ordered_multimap =
tree <Key, T, less_equal <Key>, rb_tree_tag, tree_order_statistics_node_update>;

#define y0 _y0_
#define y1 _y1_
#define div divi
typedef long long ll;
typedef long double ld;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <ld> vld;
typedef vector <string> vs;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <vi > vvi;
typedef vector <vll > vvll;
typedef vector <pii > vpii;
typedef vector <pll > vpll;

const int N = 2e6 + 5;
int mod = 1e9 + 7, mod1 = 998244353, mod2 = 1e9 + 9, inf = 1e9 + 7;
ll infll = 1e18 + 7;

int la, lb;
int a[N], b[N];

bool ck(int x, int y, int z){
    if (!z) return 0;
    if (x > y) y += lb;
    if (y > z) z += lb;
    return (y <= z && z - x < lb);
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> la >> lb;
    ForE(i, 1, la){
        cin >> a[i];
        a[la + i] = a[i];
    }
    ForE(i, 1, lb){
        int x; cin >> x;
        b[x] = i;
    }
    int i = 1, j = 1, ans = 0;
    while (i <= la){
        if (!b[b[i]]){
            i++;
            continue;
        }
        j = max(j, i);
        while (j - i + 1 <= la && ck(b[a[i]], b[a[j]], b[a[j + 1]])) j++;
        ans = max(ans, j - i + 1);
        i++;
    }
    cout << ans;
}

/*
==================================+
INPUT:                            |
------------------------------    |

------------------------------    |
==================================+
OUTPUT:                           |
------------------------------    |

------------------------------    |
==================================+
*/

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <map>
#include <algorithm>

#define mod 1000000007
#define inf 2000000000
#define forn(var, size) for(int var = 0; var < (int)(size); ++var)

using namespace std;

typedef vector<int> vi;
typedef vector< vector<int> > vvi;
typedef vector<bool> vb;
typedef pair<int, int> ii;

int a[1000500];
int b[1000500];
int c[1000500];
int q[2000500];

int main(int argc, char **argv) {
	int la, lb;
	scanf("%d %d", &la, &lb);
	forn(i, la)
		scanf("%d", a + i);
	forn(i, lb) {
		scanf("%d", b + i);
		c[b[i]] = i + 1;
	}
	int sz = 0;
	int qs = 1000010;
	int qe = qs;
	int curs = c[a[la - 1]];
	int curm = lb + 1;
	if(curs)
	for(int k = la - 1; k >= 0; k--) {
		int dig = a[k];
		int cp = c[dig] - curs;
		if(cp <= 0)
			cp += lb;
		if(k == la - 1)
			curs = cp;
//		cout << a[k] << " " << cp << " " << curm << endl;
		if(c[dig] && cp < curm) {
			sz++;
			curm = cp;
			q[--qs] = cp;
		} else
			break;
	}
	int ans = sz;
	for(int i = 0; i < la; i++) {
		if(c[a[i]]) {
			int cp = c[a[i]] - curs;
			while(cp <= 0)
				cp += lb;
			curs += cp;
			q[qe++] = curs;
			while(qs < qe && q[qs] <= curs - lb)
				qs++;
//			cout << a[i] << ": " << cp << ' ' << curs << ' ' << qs << ' ' << qe << endl;
		} else {
			qs = qe = 1000010;
		}
		ans = max(ans, qe - qs);
	}
	cout << ans << endl;
	return 0;
}

#include <cstring>
#include <cstdio>
const int N=1001000;
int t[N],s[N],n,m;
int cnt[N],co[N];
int ans;
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
void check()
{
    //printf("--%d\n",k);
    //if(k==0)return true;
    int L=1,R=1;
    int first=co[L],last=co[R];
    while(L<=n&&R<2*n)
    {
        if(first==0)
        {
            R=++L;
            last=first=co[L];
            continue;
        }
        while(L<=n&&R<2*n)
        {
            //printf("%d %d %d %d\n",L,R,first,last);
            if(R-L+1>ans)ans=R-L+1;
            ++R;
            if(co[R]==0)
            {
                L=++R;
                last=first=co[L];
                break;
            }
            if(first <= last)
            {
                if(co[R]>last)last=co[R];
                else if(co[R]<first)last=co[R];
                else
                {
                    while(co[++L]<co[R]);
                    first=co[L];
                    last=co[R];
                }
            }
            else
            {
                if(co[R]>last&&co[R]<first)
                    last=co[R];
                else if(last > co[R])
                {
                    while(1)
                    {
                        ++L;
                        if(co[L]>co[R] && co[L] <=last)
                            break;
                    }
                    first=co[L];
                    last=co[R];
                }
                else if(co[R]>first)
                {
                    while(1)
                    {
                        ++L;
                        if(co[L] > co[R] || co[L] <= last)
                            break;
                    }
                    first=co[L];
                    last=co[R];
                }
            }

        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t[i]);
        cnt[t[i]]=i;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&s[i]);
        if(cnt[s[i]]!=0)
            co[cnt[s[i]]+n]=co[cnt[s[i]]]=i;
    }
    check();
    if(ans>=min(n,m))ans=min(n,m);
    printf("%d\n",ans);
    scanf(" ");
}
/*
10 10
9 12 15 2 4 14 1 5 6 13
12 11 13 1 4 3 8 2 14 15

*/

#pragma comment(linker, "/STACK:16777216")

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<algorithm>
#include<list>
using namespace std;

#define pb push_back
#define MS( a ) memset( a,0,sizeof(a))
#define MSV( a,v ) memset( a,v,sizeof(v))

#define MAX 1000007

long l1,l2;
long s1[2*MAX+7];
long Ind[MAX+7];

bool Inside( long l,long r,long i )
{
	if( l<=r ){
		return i>=l && i<=r;
	}
	else{
		return i>=l || i<=r;
	}
}

int main( void )
{
    long i,j,v;

    cin>>l1>>l2;
    for( i=0;i<l1;i++ ){
		cin>>s1[i];
		s1[l1+i] = s1[i];
	}
	memset( Ind,-1,sizeof(Ind));
	for( i=0;i<l2;i++ ){
		cin>>v;
		Ind[v] = i;
	}

	long Lim = 2*l1;
	long qL,qR,qS = 0;
	long L = 0,R = l2-1;
	long Ans = 0;
	for( i=0;i<Lim;i++ ){
		if( Ind[s1[i]]==-1 ){
			qS = 0;
		}
		else if( !qS ){
			qL = qR = i;
			qS = 1;
		}
		else if( qS<l1 && Inside( L,R,Ind[s1[i]]) ){
			qR++;
			qR %= l1;
			qS++;
		}
		else{
			qR %= l1;
			qS--;
			i--;
		}
		if( qS ){
			L = (Ind[qR]+1)%l2;
			R = (Ind[qL]+l2)%l2;
		}
		//printf("Range  %ld %ld\n",L,R );
		Ans = max( Ans,qS );
		//cout<<q.size()<<endl<<endl;
		//cin>>v;
	}
	Ans = max( Ans,(long)qS );

	cout<<Ans<<endl;

	//cin>>i;

    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <string>
using namespace std;
#define FOR(i, a, b) for(int i=a; i<=b; i++)
#define DOW(i, a, b) for(int i=a; i>=b; i--)
#define FOREACH(it, c) for(typeof(c.begin()) it=c.begin(); it!=c.end(); it++)
#define RESET(c, val) memset(c, val , sizeof(c))
#define maxn 1000006

int m, n, a[maxn*2], x, pos[maxn];

int main() {
    freopen("test.inp", "r", stdin);
    freopen("test.out", "w", stdout);
    cin >> m >> n;
    FOR(i, 1, m) scanf("%d", &a[i]), a[i+m]=a[i];
    RESET(pos, 0);
    FOR(i, 1, n) scanf("%d", &x), pos[x]=i;

    int res=0, pp=0;
    FOR(i, 1, m) {
        pp=max(pp, i+1);
        while (pp<=i+m-1 && pos[a[pp]]!=0 &&
           ((pos[a[pp]]>pos[a[pp-1]] && pos[a[pp]]<pos[a[i]])
         || (pos[a[pp]]>pos[a[pp-1]] && (pos[a[pp-1]]>pos[a[i]] || pp-1==i))
         || (pos[a[pp]]<pos[a[i]]    && (pos[a[pp-1]]>pos[a[i]] || pp-1==i)))) pp++;
        if (pos[a[i]]!=0) res=max(res, pp-i);
    }
    cout << res;
    //system("pause");
    return 0;
}

/* Writen by Filip Hlasek 2012 */
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstring>

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,b) for(int i=0;i<b;i++)

using namespace std;

#define MAXN 1111111
int a[2*MAXN],b[MAXN],A,B;
int pos[MAXN];

int main(int argc, char *argv[]){
  REP(i,MAXN) pos[i] = -1;
  scanf("%d%d",&A,&B);
  REP(i,A){
    scanf("%d",a+i);
    a[A+i] = a[i];
  }
  REP(i,B) scanf("%d",b+i);
  REP(i,B) pos[b[i]] = i;
  int start = 0, end = 0, best = 0;
  while(start < A && pos[a[start]] == -1) start++;
  if(start == A){ printf("0\n"); return 0; }
  end = start;
  bool over = false;
  while(start < A){
    //printf("start:%d end:%d over:%d - next:%d pos-start:%d\n",start,end,(int)over,pos[a[end+1]],pos[start]);
    while(true){
      if(pos[a[end+1]] == -1) break;
      if(pos[a[end+1]] > pos[a[end]] && (!over || pos[a[end+1]] < pos[a[start]])){ end++; continue; }
      if(!over && pos[a[end+1]] < pos[a[start]]){
        over = true;
        end++;
      }
      else break;
    }
    /*
    while(pos[a[end+1]] != -1 && ((!over && (pos[a[end+1]] > pos[a[end]] || pos[a[end+1]] < pos[a[start]])) ||
                                            (pos[a[end+1]] > pos[a[end]] && pos[a[end+1]] < pos[a[start]]))){
      if(pos[a[end+1]] <= pos[a[end]]) over = true;
      end++;
    }
    */
    //printf("...start:%d end:%d over:%d\n",start,end,(int)over);
    best = max(best, end - start + 1);
    start++;
    if(end < start){
      over = false;
      while(start < A && pos[a[start]] == -1) start++;
      end = start;
    }
  }
  printf("%d\n",best);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+5, K = 20;
typedef long long ll;
int n,m;
ll dist[N][K];
vector<int> a,b;
int pos[N];
int main(){
    cin >> n >> m;
    a.resize(n);
    b.resize(m);
    for(int i = 0; i < n; ++i)
        scanf("%d",&a[i]);
    for(int i = 0; i < m; ++i)
        scanf("%d",&b[i]);
    vector<int> convert(N,-1);
    for(int i = 0; i < n; ++i)
        convert[a[i]] = i;
    for(int i = 0; i < m; ++i)
        b[i] = convert[b[i]];
    {
        vector<int> new_b;
        for(int i = 0; i < m; ++i)
            if(b[i] != -1)
                new_b.push_back(b[i]);
        b = new_b;
        m = b.size();
    }
    if(m == 0){
        puts("0");
        return 0;
    }
    for(int i = 0; i < n; ++i){
        dist[i][0] = N;
        pos[i] = N*2;
    }
    for(int i = 0; i < m; ++i)
        pos[b[i]] = i;
    for(int i = 0; i < m; ++i){
        dist[b[i]][0] = pos[(b[i]+1)%n] - i;
        if(dist[b[i]][0] < 0)
            dist[b[i]][0] += m;
    }
//    for(int i = 0; i < n; ++i) cout << a[i] << " \n"[i==n-1];
//    for(int i = 0; i < m; ++i) cout << b[i] << " \n"[i==m-1];
    for(int s = 1; s < K; ++s)
        for(int i = 0; i < n; ++i)
            dist[i][s] = min((ll)N,dist[i][s-1] + dist[(i+(1<<(s-1)))%n][s-1]);
    int ans = 0;
//    cout << dist[4][0] << '\n';
    for(int i = 0; i < n; ++i){
        if(pos[i] >= N)
            continue;
        int cur = 1, u = i;
        ll total = 0;
        for(int s = K-1; s >= 0; --s){
            if(total + dist[u][s] < m){
                total += dist[u][s];
                u = (u + (1<<s))%n;
                cur += 1<<s;
            }
        }
        ans = max(ans,cur);
    }
    cout << ans << '\n';
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <utility>
#include <math.h>
#include <cstdlib>
#include <memory.h>
#include <queue>

#define pb push_back
#define i64 long long
#define mp make_pair
#define pii pair <int,int>
#define vi vector <int>
#define vii vector <pii>
#define f first
#define s second
#define foran(i,a,b) for (int i=a;i<(int)b;i++)
#define forn(i,n) for (int i=0;i<(int)n;i++)
#define ford(i,n) for (int i=(int)n-1;i>=0;i--)

const double eps = 1e-9;
const int int_inf = 2000000000;
const i64 i64_inf = 1000000000000000000LL;
const double pi = acos(-1.0);

using namespace std;
int wa[1000010];
int wb[1000010];
int a[1000100];
int b[1000100];
int la,lb;
int res = 0;

int main() {
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
  memset(wa,-1,sizeof(wa));
  memset(wb,-1,sizeof(wb));
  cin >> la >> lb;
  forn(i,la) scanf("%d",&a[i]), wa[a[i]] = i;
  forn(i,lb) scanf("%d",&b[i]), wb[b[i]] = i;

  int f = wb[a[0]],last = f,len = 0;

  if (f != -1)
  {
   foran(i,1,la)
   {
     if (wb[a[i]] == -1) { len = i; break; }
     if (f <= last)
         if (wb[a[i]] > last || wb[a[i]] < f) { last = wb[a[i]]; continue; } else { len = i; break; }
      if (wb[a[i]] > last && wb[a[i]] < f) { last = wb[a[i]]; continue; } else { len = i; break; }
   }
  }

  res = max(res,len);

  foran(i,1,la)
  {
//  cout << "a[i] == " << a[i-1] << endl;
//  cout << "after " << i << " iteration " << "f = " << f << " last = " << last << " len = " << len << endl;
    if (len == 0)
    {
        if (wb[a[i]] == -1) continue;
        f = last = wb[a[i]];
        len = 1;
    } else
    {
        len--;
        f = wb[a[i]];
        if (f == -1) { len = 0; continue; }
    }

    int j = (i + len) % la;

    while (j != i)
    {
//      cout << " ->" << j << " ";
        if (wb[a[j]] == -1) break;
        if (f <= last)
            if (wb[a[j]] > last || wb[a[j]] < f) { last = wb[a[j]]; len++; j = (j+1)%la; continue; } else break;
        if (wb[a[j]] > last && wb[a[j]] < f) { last = wb[a[j]]; len++; j = (j+1)%la; continue; } else break;
    }

    res = max(res,len);
//  cout << endl;
  }

//    cout << "a[i] == " << a[la-1] << endl;
//  cout << "after " << la << " iteration " << "f = " << f << " last = " << last << " len = " << len << endl;
  cout << res << endl;
  return 0;
}

#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
using namespace std;
const int N = 1000005;
vector<int>q[N];
int k,t[N],f[N],r,a[N],b[N+N],pos[N],nxt[N];
int main()
{
    int n,m,i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
    {
        scanf("%d",a+i);
    }
    for(i=1;i<n;i++)nxt[a[i]]=a[i+1];
    nxt[a[n]]=a[1];
    for(i=1;i<=m;i++)
    {
        scanf("%d",b+i);
        b[m+i]=b[i];
        pos[b[i]]=i;
    }
    k=0;
    for(i=1;i<=m+m;i++)
    {
        int j=nxt[b[i]];
        if(!f[i])
        {
            q[++k].push_back(i);
            f[i]=k;
        }
        int s=f[i];
    //printf("i:%d b[i]:%d j:%d s:%d \n",i,b[i],j,s);
        if(j&&pos[j])
        {
            int p=pos[j];
            if(p<i)p+=m;
            if(p>i)
            {
                while(t[s]<q[s].size()&&p-q[s][t[s]]>=m)t[s]++;
                q[s].push_back(p);
        //      printf("p:%d t[s]:%d size:%d \n",p,t[s],q[s].size());
                f[p]=s;
            }
        }
        if(r<q[s].size()-t[s])r=q[s].size()-t[s];
    //  printf("i:%d r:%d s:%d qs:%d \n",i,r,s,q[s].size());
    }
    if(r>n)r=n;
    printf("%d\n",r);
    return 0;
}

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <deque>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int n, m;
int seq[1000010];
int rev[1000010];

int D(int next, int prev) {
  int d = rev[next % n] - rev[prev % n];
  if (d < 0) { d += m; }
  return d;
}

int main() {
  while (scanf("%d %d", &n, &m) > 0) {
    MEMSET(rev, -1);
    {
      map<int, int> mapto;
      REP(i, n) {
        int v = 0;
        scanf("%d", &v);
        mapto[v] = i;
      }
      int cnt = 0;
      REP(i, m) {
        int v;
        scanf("%d", &v);
        if (!mapto.count(v)) { continue; }
        v = mapto[v];
        rev[v] = cnt;
        seq[cnt++] = v;
      }
      m = cnt;
    }

    int ans = 0;
    int head = 0;
    int tail = 0;
    int len = 0;
    while (tail < n) {
      if (rev[head % n] == -1) {
        len = 0;
        tail = head + 1;
        head = head + 1;
        continue;
      }
      if (head - tail == 0) {
        head++;
      } else {
        len += D(head, head - 1);
        head++;
        while (len > m) {
          len -= D(tail, tail - 1);
          tail++;
        }
      }
      ans = max(ans, head - tail);
      if (ans == m) { break; }
    }
    printf("%d\n", ans);
  }
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.14159265358979
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

using namespace std;
int c[2000010];
vector<int> a;
int b[1000010];
int pos[1000010];
int f[2000010];
int main()
{
	//freopen("in.txt","r",stdin);
	int res=0;
	int n,m;
	MEMS(pos,-1);
	scanf("%d%d",&n,&m);
	FOR(i,0,n)
	{
		scanf("%d",&c[i]);
		c[n+i]=c[i];
	}
	FOR(i,0,m)
	{
		scanf("%d",&b[i]);
		pos[b[i]]=i;
	}
	int l=0,r=0;
	int cur=0;
	FOR(i,0,n+n)
		if (pos[c[i]]!=-1)
			a.push_back(c[i]);
	n=a.size()/2;
	while ((l<n+n) && (r<n+n-1))
	{
		if (r-l==n)
		{
			l++;
			cur^=f[l];
			continue;
		}
		res=max(res,r-l+1);
		if (pos[a[r+1]]>=pos[a[r]])
		{
			if (cur)
			{
				if (pos[a[r+1]]<pos[l])
				{
					r++;
				}
				else
				{
					l++;
					cur^=f[l];
				}
			}
			else
				r++;
		}
		else
		{
			if (cur)
			{
				l++;
				cur^=f[l];
			}
			else
			{
				if (pos[a[r+1]]<pos[a[l]])
				{
					cur=1;
					r++;
					f[r]=1;
				}
				else
				{
					l++;
					cur^=f[l];
				}
			}
		}
	}
	cout<<res<<endl;
	return 0;
}

#include <vector>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
#define REP(i,n) for(int i=0;i<(n);i++)

int nextint()
{
	int t;
	scanf("%d",&t);
	return t;
}

int s1[1000001];
int s2[1000001];
int p[1000001];
int m[1000001];

int l1,l2;

int getlen(int l,int r)
{
	if(l<=r)
		return (r-l+1);
	else
		return getlen(l,r+l1);

}

int main()
{

	l1=nextint();
	l2=nextint();
	REP(i,l1)
		s1[i]=nextint();
	REP(i,l2)
		s2[i]=nextint();
	memset(m,-1,sizeof(m));
	REP(i,l2)
		m[s2[i]]=i;
	REP(i,l1)
		p[i]=m[s1[i]];
	int l=-1,r=-1;
	REP(i,l1)
	{
		if(p[i]!=-1)
		{
			l=r=i;
			break;
		}
	}
	if(l==-1)
	{
		printf("0\n");
		return 0;
	}
	while(1)
	{
		int np=p[(r+1)%l1];
		if(np==-1) break;
		if(p[l]<=np&&np<=p[r]) break;
		if(p[l]>p[r]&&(!(p[l]<=np&&np<=p[r]))) break;
		r=(r+1)%l1;
	}
	int res=getlen(l,r);
	REP(i,l1)
	{
		l=(l+1)%l1;
		///???
		if(p[l]==-1)
		{
			r=(l+1)%l1;
			continue;
		}
		while(1)
		{
			int np=p[(r+1)%l1];
			if(np==-1) break;
			if(p[l]<=np&&np<=p[r]) break;
			if(p[l]>p[r]&&(!(p[l]<=np&&np<=p[r]))) break;
			r=(r+1)%l1;
		}
		res=max(res,getlen(l,r));
	}
	printf("%d\n",res);
	return 0;
}

#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <utility>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <ctime>
#include <queue>
//#include <cmath>
#include <deque>
#include <list>
#include <sstream>
#include <bitset>
#include <complex>
#pragma comment(linker, "/STACK:16777216")
#pragma warning(default :4)
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define eps 1e-9
#define INF 1000000001
#define oo 1000000001
#define MOD 1000000007
#define cint const int &
#define cll const ll &
#define cull const ull &
#define FOR(i, x) for (int i = 0; i < (int)(x); ++i)
#define CL(x) memset(x, 0, sizeof(x))
#define SVAL(x, y) memset(x, y, sizeof(x))
#define FIN freopen("in.txt", "r", stdin);
#define VINT vector<int>
#define PII pair<int, int>
#define y1 Y1
using namespace std;
typedef complex<double> Cn;
int n, m;
int p[1<<21], s1[1<<21], s2[1<<21], d[1<<21], r, q[1<<21], lb;//pr[1<<21], dl[1<<21], dr[1<<21], r;
int main()
{
    scanf("%d %d", &n, &m);
    SVAL(p, -1);
    for (int i=0; i<n; i++)
    {
        scanf("%d", &s1[i]);
        s1[i+n]=s1[i];
        p[s1[i]]=i;
        //pr[s1[i]]=i;
    }
    for (int i=0; i<m; i++)
    {
        scanf("%d", &s2[i]);
        s2[i+m]=s2[i];
        //p[s2[i]]=i;
    }
    for (int i=0; i<2*m; i++)
    {
        int &pos=p[s2[i]];
        int &qu=q[s2[i]];
        qu++;
        if (qu==2)
        {
            lb=max(lb, pos);
        }
        if (pos==-1) continue;
        if (pos) d[pos]=min(pos-lb, 1+d[pos-1]);
        r=max(r, d[pos]);
        pos+=n;
        d[pos]=min(pos-lb, 1+d[pos-1]);
        r=max(r, d[pos]);
    }
    /*int p1=p[s1[0]];
    if (p1!=-1)
    {
        dl[0]=1;
        dr[0]=1;
    }
    for (int i=1; i<2*n; i++)
    {
        int &p2=p[s1[i]];
        int &p1=p[s1[i-1]];
        if (p1<p2)
        {
            dl[i]=dl[i-1]+1;
            dr[i]=dr[i-1]+1;
        }
        else
        {
            int &d=pr[s
            dl[i]=1;
            dr[i]=dl[i-1]+1;
        }
        r=max(r, dl[i]);
        r=max(r, dr[i]);
    }*/
    printf("%d\n", min(r, n));
    return 0;
}

#pragma comment (linker, "/STACK:64000000")
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
#include <cctype>
#include <bitset>
#include <sstream>
#include <set>
#include <map>

using namespace std;
template <class T> T sqr(T a) { return a * a; }
const int maxn = 1001000;

int la, lb;
int a[maxn];
int b[maxn];
int f[maxn];

int getb(int id)
{
    return f[a[id]];
}

int check_inside(int st, int f, int v)
{
    return st < f ? st < v && v < f : st < v || v < f;
}

int main()
{
#ifdef IMPETUS
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    cin >> la >> lb;
    for (int i = 0; i < la; i++)
        cin >> a[i];
    for (int i = 0; i < lb; i++)
    {
        cin >> b[i];
        f[b[i]] = i;
    }
    int best = 0;
    int prev;
    int st = -1;
    for (int iter = 0; iter < 2; iter++)
        for (int i = 0; i < la; prev = i, i++)
            if (getb(i) + 1)
            {
                if (st == -1)
                    st = i;
                while (st != i && st != prev && check_inside(getb(st), getb(prev), getb(i)))
                    st = (st + 1) % la;
                best = max(best, (i - st + la) % la + 1);
            }
    cout << best;
    return 0;
}

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <map>
#include <algorithm>

#define mod 1000000007
#define inf 2000000000
#define forn(var, size) for(int var = 0; var < (int)(size); ++var)

using namespace std;

typedef vector<int> vi;
typedef vector< vector<int> > vvi;
typedef vector<bool> vb;
typedef pair<int, int> ii;

int a[1000500];
int b[1000500];
int c[1000500];
long long q[2000500];

int main(int argc, char **argv) {
	int la, lb;
	scanf("%d %d", &la, &lb);
	forn(i, la)
		scanf("%d", a + i);
	forn(i, lb) {
		scanf("%d", b + i);
		c[b[i]] = i + 1;
	}
	int sz = 0;
	int qs = 1000010;
	int qe = qs;
	long long curs = c[a[la - 1]];
	int curm = lb + 1;
	if(curs)
	for(int k = la - 1; k >= 0; k--) {
		int dig = a[k];
		int cp = c[dig];
		if(cp > curs)
			cp -= lb;
//		if(k == la - 1)
//			curs = cp;
//		cp -= lb;
//		cout << a[k] << " " << cp << " " << curm << endl;
		if(c[dig] && cp < curm) {
			sz++;
			curm = cp;
			q[--qs] = cp;
		} else
			break;
	}
	int ans = sz;
	for(int i = 0; i < la; i++) {
		if(c[a[i]]) {
			long long cp = c[a[i]] - curs;
			cp %= lb;
			while(cp < 0)
				cp += lb;
			curs += cp;
			q[qe++] = curs;
			while(qs < qe && q[qs] <= curs - lb)
				qs++;
//			cout << a[i] << ": " << cp << ' ' << curs << ' ' << qs << ' ' << qe << endl;
		} else {
			qs = qe = 1000010;
		}
		ans = max(ans, qe - qs);
	}
	cout << ans << endl;
	return 0;
}

/*
 * File: B.cpp
 * Author: wym510
 * Email: <wym6110@gmail.com>
 * Create Date: 2012-4-8 23:33:01
*/

#include <vector>
#include <string>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define S size()
#define B begin()
#define E end()
#define P push_back
#define fu(i,a,b) for(int i=a;i<b;++i)
#define fd(i,a,b) for(int i=b-1;i>=a;--i)
typedef long long int64;
using namespace std;

const int MaxN=3200000;
const int MaxM=3200000;
const int MaxNum=3200000;

int va[MaxN],vb[MaxM];
int pos[MaxNum];
int q[MaxN*2];

int main()
{
    int n,m;

    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",va+i);
    for(int i=1;i<=n;i++) va[i+n]=va[i];
    for(int i=1;i<=m;i++)
    {
        scanf("%d",vb+i);
        pos[vb[i]]=i;
    }

    int ans=0,ff=0,rr=0;

    for(int i=1,j=1;i<=2*n;i++)
    {
        while(j<=2*n)
        {
            if(pos[va[j]]==0) break;

            int kk=pos[va[j]];

            if(ff==rr) q[rr++]=kk;
            else
            {
                kk+=(q[rr-1]/m)*m;
                if(q[rr-1]>kk) kk+=m;
                if(kk-q[ff]>=m) break;
                q[rr++]=kk;
            }
            j++;
        }
        ans=max(ans,j-i);
        if(ff<rr) ff++;
        if(i==j) j++;
    }

    cout<<ans<<endl;
    return 0;
}

/* vim: set ts=4 sw=4: */

#include <cstdio>
#include <deque>

int a[1000001];
int p[1000001];

int main() {
  int l, r, i, c; scanf("%d%d", &l, &r);
  for (i = 0; i < l; ++i) scanf("%d", &a[i]);
  for (i = 1; i <= r; ++i) scanf("%d", &c), p[c] = i;
  std::deque<int> q;
  for (i = r = 0; i < 2*l; ++i) {
    c = p[a[i%l]];
    if (c) {
      while (q.size() >= 2 && ((q[0] < q.back()) ^ (c < q[0] && c > q.back())))
        q.pop_front();
      q.push_back(c);
    } else q.clear();
    r = std::max((int)q.size(), r);
  }
  printf("%d", std::min(l, r));
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#include <ctime>
#include <memory.h>
#include <string>
#include <sstream>
#include <map>

#define ll long long

using namespace std;

int f[1000002];
int s[1000002];
int w1[1000002];
int w2[1000002];
vector <int> v;

int main()
{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    for(int i=0;i<=1000000;++i) w1[i]=w2[i]=-1;
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i) {
        scanf("%d",&f[i]);
        w1[f[i]]=i;
    }
    for(int i=0;i<m;++i) {
        scanf("%d",&s[i]);
        w2[s[i]]=i;
    }
    int ans=0,st=-1,last=-1,len=0;
    for(int i=0;i<n;++i) {
        if (w2[f[i]]==-1) break;
        if (st==-1) {
            st=last=w2[f[i]],len=1;
            v.push_back(st);
        }
        else {
            int npos=w2[f[i]];
            if (npos<st) npos+=m;
            if (npos-st+1<=m&&npos>last) {
                ++len;
                last=npos;
                v.push_back(last);
            } else break;
        }
        if (len==n||len==m) break;
    }
    ans=len;
    int vcur=len==0 ? -1 : 1;
    for(int i=1;i<n;++i) {
        if (w2[f[i]]==-1) {
            len=0;
            st=last=-1;
            v.clear();
            vcur=-1;
            continue;
        }
        if (vcur==-1) {
            for(int j=0;j<n;++j) {
                if (w2[f[(j+i)%n]]==-1) break;
                if (st==-1) {
                    st=last=w2[f[(j+i)%n]],len=1;
                    v.push_back(st);
                }
                else {
                    int npos=w2[f[(j+i)%n]];
                    if (npos<st) npos+=m;
                    if (npos-st+1<=m&&npos>last) {
                        ++len;
                        last=npos;
                        v.push_back(last);
                    } else break;
                }
                if (len==n||len==m) break;
            }
            ans=max(ans,len); vcur=0;
        } else {
            st=v[vcur]%m; --len;
            if (last-st>=m) last-=m;
            for(int j=0;j<n;++j) {
                if (w2[f[(i+len)%n]]==-1) break;
                if (st==-1) {
                    st=last=w2[f[(i+len)%n]],len=1;
                    v.push_back(st);
                }
                else {
                    int npos=w2[f[(len+i)%n]];
                    if (npos<st) npos+=m;
                    if (npos-st+1<=m&&npos>last) {
                        ++len;
                        last=npos;
                        v.push_back(last);
                    } else break;
                }
                if (len==n||len==m) break;
            }
            ans=max(ans,len); vcur++;
        }
    }
    printf("%d\n",ans);
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <utility>
#include <vector>
#include <set>
#include <algorithm>

#define maxn 1000010
#define Fup(i, s, t) for (int i = s; i <= t; i ++)
#define Fdn(i, s, t) for (int i = s; i >= t; i --)
#define Path(i, s) for (int i = s; i; i = d[i].next)

using namespace std;

int x[maxn * 2], pos[maxn];
int l1, l2;

void init()
{
    cin >> l1 >> l2;
    Fup(i, 1, l1)
        cin >> x[i];
    Fup(i, l1 + 1, l1 + l1)
        x[i] = x[i - l1];
    Fup(i, 1, l2){
        int t;
        cin >> t;
        pos[t] = i;
    }
}

void solve()
{
    int head = 1, mid, tail = 1, ans = 0, t = 0;
    while (head <= l1){
        while (pos[x[tail]] == 0){
            ans = max(ans, tail - head);
            head = tail = tail + 1;
            t = 0;
        }
        if (t == 0){
            while (pos[x[tail]] < pos[x[tail + 1]])
                tail ++;
            if (pos[x[tail + 1]] < pos[x[head]]){
                tail ++;
                t ++;
                mid = tail;
            }else{
                ans = max(ans, tail - head + 1);
                head = tail = tail + 1;
                t = 0;
            }
        }else{
            while (pos[x[tail]] < pos[x[tail + 1]] && pos[x[tail + 1]] < pos[x[head]])
                tail ++;
            ans = max(ans, tail - head + 1);
            t = 0;
            head = mid;
        }
    }
    cout << ans << endl;
}

int main()
{
//    freopen("temp.in", "r", stdin);
//    freopen("temp.out", "w", stdout);
    ios::sync_with_stdio(false);
    init();
    solve();
    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <iomanip>
#include <cmath>
#include <sstream>
//#include <windows.h>

using namespace std;

/*void timer (string s)
{
	SYSTEMTIME time;
	GetSystemTime(&time);
	WORD millis = (time.wSecond * 1000) + time.wMilliseconds;
	cerr << s << ' ' << millis << endl;
}*/

#define pie pair <int, int>
#define ff first
#define ss second

const int maxN = 2000 * 1000 + 100;

int n, m;
int a[maxN], b[maxN], bm[maxN];

int main()
{
	ios::sync_with_stdio (false);

	cin >> n >> m;
	for (int i = 0; i < n; i++) cin >> a[i], a[n + i] = a[i];
	for (int i = 0; i < m; i++) cin >> b[i], b[m + i] = b[i];
	memset (bm, -1, sizeof bm);
	for (int j = 0; j < m; j++) bm[b[j]] = j;

	int best = 0;
	for (int i = 0, j = 0, k = 0; i < 2 * n; i++)
		if (bm[a[i]] == -1) k = j = i + 1;
		else {
			if (i && bm[a[i]] > bm[a[i - 1]])
				while (j < k && bm[a[j]] < bm[a[i]]) j++;
			else if (i) {
				j = k, k = i;
				while (j < k && bm[a[j]] < bm[a[i]]) j++;
			}
			best = max (best, i - j + 1);
		}
	cout << best << endl;

	cin >> n;
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int n, m;
int x[2000100], y[1000100], p[1000100];

void init()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", &x[i]);
        x[i+n] = x[i];
    }
    memset(p, 0, sizeof(p));
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d", &y[i]);
        p[y[i]] = i;
    }
}

int ans = 0;

void work()
{
    int j = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (!p[x[i]]) continue;
        if (i > 1 && p[x[i+1]]) j = max(j, i + 2);
        else j = i + 1;
        while (j - i < n && p[x[j]] && ((p[x[i]] < p[x[j-1]] && !(p[x[j]] < p[x[j-1]] && p[x[j]] > p[x[i]])) || (p[x[j]] > p[x[j-1]] && p[x[i]] > p[x[j]])))
            ++j;
        ans = max(ans, j - i);
    }
    printf("%d\n", ans);
}

int main()
{
    init();
    work();
    return 0;
}

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN = 1e6 + 10;
struct node
{
    int bgin, end;
}Seq[MAXN];
int a[MAXN], b[MAXN];
int la, lb;

int max(int a, int b)
{
    return a > b ? a : b;
}

void solve()
{
    int i = 1;
    while(i <= la && a[i] == 0) i++;

    //都是0；
    if(i > la)
    {
        puts("0");
        return;
    }

    //建预处理出连续递增序列。
    int tot = 0;
    Seq[tot].bgin = i;
    for(i = i + 1; i <= la; i++)
    {
        if(a[i] == 0 && a[i - 1] != 0)
        {
            Seq[tot].end = i;
            continue;
        }

        if(a[i] > a[i - 1])
        {
            if(a[i - 1] == 0)
            {
                tot++;
                Seq[tot].bgin = i;
            }
        }
        else
        {
            Seq[tot].end = i;
            tot++;
            Seq[tot].bgin = i;
        }
    }

    i = la;
    while(i >= 1 && a[i] == 0) i--;
    Seq[tot].end = i + 1;

    //处理答案；
    int ans = 0;
    for(i = 0; i + 1 <= tot; i++)
    {
        if(Seq[i].end != Seq[i + 1].bgin)
        {
            ans = max(ans, Seq[i].end - Seq[i].bgin);
            continue;
        }

        for(int j = Seq[i].bgin; j < Seq[i].end; j++)
        {
            int tmp = Seq[i].end - j + (lower_bound(a + Seq[i + 1].bgin, a + Seq[i + 1].end, a[j]) - (a + Seq[i + 1].bgin));
            ans = max(ans, tmp);
        }
    }

    //如果最后一个序列不能和第一个序列相连，则输出答案；
    if(!(Seq[tot].end == la + 1 && Seq[0].bgin == 1))
    {
        printf("%d\n", ans);
        return;
    }

    //最后一个序列和第一个序列相连。
    for(int i = Seq[tot].bgin; i < Seq[tot].end; i++)
    {
        int tmp = Seq[tot].end - i + lower_bound(a + Seq[0].bgin, a + Seq[0].end, a[i]) - (a + Seq[0].bgin);
        ans = max(ans, tmp);
    }
    printf("%d\n", ans);
}

int main()
{
    //freopen("data.in", "r", stdin);

    scanf("%d%d", &la, &lb);
    for(int i = 1; i <= la; i++) scanf("%d", &a[i]);
    for(int i = 1; i <= lb; i++)
    {
        int t;
        scanf("%d", &t);
        b[t] = i;
    }

    for(int i = 1; i <= la; i++)
    {
        a[i] = b[a[i]];
    }

    solve();

    return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;

#define N 100000
int a[N], b[N], dp[N], h[N+1];

int main() {
    int n, m, i, j, k;
    cin>>n>>m;
    memset(h, -1, sizeof(h));
    for (i=0; i<n; i++) cin>>a[i];
    for (i=0; i<m; i++) {
        cin>>b[i];
        h[b[i]] = i;
    }
    int res = 0, left = -1;
    if (h[a[0]] != -1) dp[0] = 1, left = 0;
        for (i=1; i<n; i++) {
        if (h[a[i]]>h[a[i-1]]) dp[i] = dp[i-1]+1;
        else dp[i] = 1;
        if (dp[i]==i+1) left = i;
        res = max(res, dp[i]);
    }
    if (h[a[left]]>h[a[n-1]]) res = max(res, dp[left]+dp[n-1]);
    cout<<res<<endl;
}

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <utility>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <iterator>

using namespace std;

typedef long long LL;
typedef pair< int, int > PRII;
typedef pair< double ,double > PRDD;
typedef vector< string > VS;
typedef vector< int > VI;

#define Size(a) ((int)a.size())
#define sqr(x) ((x)*(x))
#define lowbit(x) ((x)&(-(x)))

#define x first
#define y second
#define p_b push_back
#define m_p make_pair
#define oo 1000000000
#define eps 1e-12
const double pi = acos(-1.0);

#define maxn 2000000 + 10

int n,m,ans = 0;
int a[maxn],b[maxn],c[maxn];

int main()
{
    int i,j,k;

	scanf("%d%d",&n,&m);
	for( i = 1 ; i <= n ; ++i )
		{
			scanf("%d",&a[i]);
			a[i+n] = a[i];
		}
	for( i = 1 ; i <= m ; ++i )
		{
			scanf("%d",&b[i]);
			c[b[i]] = i;
		}

	for( i = 1 ; i <= 2*n ; i = max(j,i+1) )
		{
			for( j = i ; j <= 2*n && ( j == i || c[a[j-1]] < c[a[j]] ) && c[a[j]] ; ++j );
			for( k = j ; k <= 2*n && ( k == j || c[a[k-1]] < c[a[k]] ) && c[a[k]] && c[a[k]] < c[a[i]] ; ++k );
			ans = max(ans,k-i);
		}
	printf("%d\n",ans);

    return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;

#define N 100000
int a[N], b[N], dp[N], h[N+1];

int main() {
    int n, m, i, j, k;
    cin>>n>>m;
    memset(h, -1, sizeof(h));
    for (i=0; i<n; i++) cin>>a[i];
    for (i=0; i<m; i++) {
        cin>>b[i];
        h[b[i]] = i;
    }
    int res = 0, left = -1;
    if (h[a[0]] != -1) dp[0] = 1, left = 0;
        for (i=1; i<n; i++) {
        if (h[a[i]]>h[a[i-1]]) dp[i] = dp[i-1]+1;
        else if (h[a[i]] != -1) dp[i] = 1;
        if (dp[i]==i+1) left = i;
        res = max(res, dp[i]);
    }
    if (h[a[0]]>h[a[n-1]]) res = max(res, dp[left]+dp[n-1]);
    cout<<res<<endl;
}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <utility>
#include <vector>
#include <set>
#include <algorithm>

#define maxn 1000010
#define Fup(i, s, t) for (int i = s; i <= t; i ++)
#define Fdn(i, s, t) for (int i = s; i >= t; i --)
#define Path(i, s) for (int i = s; i; i = d[i].next)

using namespace std;

int x[maxn * 2], pos[maxn];
int l1, l2;

void init()
{
    cin >> l1 >> l2;
    Fup(i, 1, l1)
        cin >> x[i];
    Fup(i, l1 + 1, l1 + l1)
        x[i] = x[i - l1];
    Fup(i, 1, l2){
        int t;
        cin >> t;
        pos[t] = i;
    }
}

void solve()
{
    int head = 1, mid, tail = 1, ans = 0, t = 0;
    while (head <= l1){
        while (pos[x[tail]] == 0){
            ans = max(ans, tail - head);
            head = tail = tail + 1;
            t = 0;
        }
        if (t == 0){
            while (pos[x[tail]] < pos[x[tail + 1]])
                tail ++;
            if (pos[x[tail + 1]] < pos[x[head]]){
                tail ++;
                t ++;
                mid = tail;
                ans = max(ans, tail - head + 1);
            }else{
                ans = max(ans, tail - head + 1);
                head = tail = tail + 1;
                t = 0;
            }
        }else{
            while (head < mid && pos[x[tail]] < pos[x[tail + 1]]){
                if (pos[x[tail + 1]] < pos[x[head]]){
                    tail ++;
                    ans = max(ans, tail - head + 1);
                }else
                    while (head < mid && pos[x[tail + 1]] >= pos[x[head]])
                        head ++;
            }
            t = 0;
            head = mid;
        }
    }
    cout << ans << endl;
}

int main()
{
//    freopen("temp.in", "r", stdin);
//    freopen("temp.out", "w", stdout);
    ios::sync_with_stdio(false);
    init();
    solve();
    return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.14159265358979
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

using namespace std;
int a[2000010];
int b[1000010];
int pos[1000010];
int f[1000010];
int main()
{
	//freopen("in.txt","r",stdin);
	int res=0;
	int n,m;
	MEMS(pos,-1);
	scanf("%d%d",&n,&m);
	FOR(i,0,n)
	{
		scanf("%d",&a[i]);
		a[n+i]=a[i];
	}
	FOR(i,0,m)
	{
		scanf("%d",&b[i]);
		pos[b[i]]=i;
	}
	int l=0,r=0;
	int cur=0;
	while ((l<n+n)&& (pos[a[l]]==-1))
	{
		l++;
		r++;
	}
	while ((l<n+n) && (r<n+n-1))
	{
		if (r-l==n)
		{
			l++;
			cur^=f[l];
			continue;
		}
		res=max(res,r-l+1);
		if ((r+1<n+n) && (pos[a[r+1]]==-1))
		{
			while ((r+1<n+n) && (pos[a[r+1]]==-1))
			{
				r++;
				l=r;
			}
			l++;
			r++;
			res=max(res,r-l+1);
			continue;
		}
		if (pos[a[r+1]]>=pos[a[r]])
		{
			if (cur)
			{
				if (pos[a[r+1]]<pos[l])
				{
					r++;
				}
				else
				{
					l++;
					cur^=f[l];
				}
			}
			else
				r++;
		}
		else
		{
			if (cur)
			{
				l++;
				cur^=f[l];
			}
			else
			{
				if (pos[a[r+1]]<pos[a[l]])
				{
					cur=1;
					r++;
					f[r]=1;
				}
				else
				{
					l++;
					cur^=f[l];
				}
			}
		}
	}
	cout<<res<<endl;
	return 0;
}

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>

#define N 1000010

using namespace std;

int a[N * 2], b[N], h[N];
long long id[N];

int main()
{
    int n, m;
    while(cin >> n >> m) {
        for(int i = 0; i < n; ++i) {
            scanf("%d", a + i);
            //cin >> a[i];
            a[i + n] = a[i];
        }
        for(int i = 1; i < N; ++i) {
            h[i] = -1;
        }
        for(int i = 0; i < m; ++i) {
            scanf("%d", b + i);
            //cin >> b[i];
            h[b[i]] = i;
        }
        int left = -1, right = 0, ans = 0;
        while(right < 2 * n) {
            ++left;
            if(h[a[right]] == -1) {
                left = right = right + 1;
            }
            if(left > right) {
                puts("fuck");
            }
            while(right < 2 * n && h[a[right]] != -1) {
                if(left == right) {
                    id[right] = h[a[right]];
                } else {
                    id[right] = id[right - 1] + (m + h[a[right]] - h[a[right - 1]]) % m;
                }
                if(left > right || id[right] < id[left]) {
                    cout << left << ' ' << right << ' ' << id[left] << ' ' << id[right] << endl;
                }
                if(id[right] - id[left] < m) {
                    ++right;
                } else {
                    break;
                }
            }
            ans = max(ans, right - left);
        }
        cout << ans << endl;
    }
    return 0;
}

#pragma comment (linker, "/STACK:64000000")
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
#include <cctype>
#include <bitset>
#include <sstream>
#include <set>
#include <map>

using namespace std;
template <class T> T sqr(T a) { return a * a; }
const int maxn = 1001000;

int la, lb;
int a[maxn];
int b[maxn];
int f[maxn];

inline int getb(int id)
{
    return f[a[id]];
}

inline int check_inside(int st, int f, int v)
{
    return st <= f ? st <= v && v <= f : st <= v || v <= f;
}

int main()
{
#ifdef IMPETUS
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    cin >> la >> lb;
    for (int i = 0; i < la; i++)
        cin >> a[i];
    memset(f, -1, sizeof(f));
    for (int i = 0; i < lb; i++)
    {
        cin >> b[i];
        f[b[i]] = i;
    }
    int best = 0;
    int prev;
    int st = -1;
    //for (int iter = 0; iter < 2; iter++)
        for (int i = 0; i < la; prev = i, i++)
            if (getb(i) + 1)
            {
                if (st == -1)
                    st = i;
                while (st != i && st != prev && check_inside(getb(st), getb(prev), getb(i)))
                    st = st == la - 1 ? 0 : st + 1;
                best = max(best, st <= i ? i - st + 1 : i - st + 1 + la);
            }
            else
                st = -1;
    cout << best;
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <queue>
#include <list>
#include <bitset>
#include <cassert>
using namespace std;
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define forit(v,it) for(typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
#define pii pair<int,int>
#define vi vector<int>
#define ll long long
#define ull unsigned long long

int n,m,a[3000000],b[3000000],pos2[2000000];

int main () {
	#ifdef LOCAL
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) {
		scanf("%d",&a[i]);
		if(i < n) a[n + i] = a[i];
	}
	for(int i=1;i<=m;++i) {
        	scanf("%d",&b[i]);
        	pos2[b[i]] = i;
        }
        int Max = 0;
        for(int i=1;i<=n;++i) {
        	if(pos2[a[i]] == 0) continue;
        	int x = pos2[a[i]];
        	int cur = x;
        	int j = 0;
        	for(j=i+1;j < i + n;++j) {
        		if(pos2[a[j]] > 0) {
        			if(pos2[a[j]] < cur  &&  pos2[a[j]] >= x) break;
        			if(pos2[a[j]] > x  &&  x > cur) break;
        			if(cur < pos2[a[j]]  &&  pos2[a[j]] < x) break;
        			if(pos2[a[j]] < cur  &&  cur < x) break;
        			cur = pos2[a[j]];
        		}
        		else break;
        	}
        	Max = max(Max,j - i);
        	i = j - 1;
        }
        printf("%d",Max);

	return 0;

}

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <cstring>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <complex>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <queue>
#include <iterator>

typedef long long LL;
typedef long double LD;

using namespace std;

const int MAX_N = 2 * 1000010;

int n, m;
int a [MAX_N], b [MAX_N], pos [MAX_N];

int brute() {
    int ret = 0;
    for (int i = 0; i < 2 * n; i++)
        for (int j = i; j < i + n; j++) {
            int cur = i;
            for (int k = 0; cur <= j && k < m; k++)
                if (b[pos[a[i]] + k] == a[cur])
                    cur++;
            if (cur > j)
                ret = max(ret, j - i + 1);
        }
    return ret;
}

int main() {
#ifndef LOCAL
//  freopen(".in", "r", stdin);
//  freopen(".out", "w", stdout);
#endif

    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        a[n + i] = a[i];
    }
    memset(pos, -1, sizeof(pos));
    for (int i = 0; i < m; i++) {
        scanf("%d", &b[i]);
        b[m + i] = b[i];
        pos[b[i]] = i;
    }

    int ans = 0;
    int i2 = 0;
    LL j1 = -m, j2 = -m;
    for (int i1 = 0; i1 < n; i1++) {
        i2 = max(i1, i2);
        while (i2 < 2 * n) {
            LL x = pos[a[i2]];
            if (x == -1)
                break;
            if (x < j2)
                x += m * ((j2 - x + m - 1) / m);
            if (j1 >= 0 && x - j1 >= m)
                break;

            i2++;
            if (j1 < 0)
                j1 = x;
            j2 = x;
#ifdef DEBUG
        cerr << "WHILE " << "i1 " << i1 << " i2 " << i2 << " j1 " << j1 << " j2 " << j2 << '\n';
#endif
        }

#ifdef DEBUG
        cerr << "i1 " << i1 << " i2 " << i2 << " j1 " << j1 << " j2 " << j2 << '\n';
#endif

        ans = max(ans, i2 - i1);

        if (i1 + 1 < i2) {
            LL x = pos[a[i1 + 1]];
            assert(x >= 0);
            if (x < j1)
                x += m * ((j1 - x + m - 1) / m);
            j1 = x;
        }
        else
            j1 = j2 = -m;
    }

#ifdef LOCAL
    int br = brute();
    if (ans != br) {
        cerr << "ans " << ans << " br " << br << '\n';
        cerr << "FUCK\n";
        assert(0);
    }
#endif
    cout << ans << '\n';
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define forit(it,S) for(typeof(S.begin()) it = S.begin(); it != S.end(); ++it)

const int maxn = 1000000;
int a[maxn + 100], b[maxn + 100];
int n, m;
int pos[maxn + 100];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i)
		scanf("%d", &a[i]);

	memset(pos, -1, sizeof(pos));
	for (int i = 0; i < m; ++i) {
		scanf("%d", &b[i]);
		pos[b[i]] = i;
	}

	int res = 0;
	int k = 0;
	for (int i = 0; i < n; ++i) {
		int first = pos[a[i]];
		if (first == -1) {
			k = 0;
			continue;
		}
		k = max(k - 1, 1);
		int j = (i + k - 1) % n;
		int sum = (pos[a[j]] - pos[a[i]] + m) % m;

		while (true) {
			int jj = (i + k) % n;
			if (pos[a[jj]] == -1) break;
			sum += (pos[a[jj]] - pos[a[j]] + m) % m;
			if (sum > m) break;
			j = jj;
			++k;
		}
		res = max(res, k);
	}
	cout << res << endl;
	return 0;
}

#include <fstream>
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <deque>
#define _USE_MATH_DEFINES
#include <math.h>
#include <string>
using namespace std;
void main()
{
	ios_base::sync_with_stdio(false);
	//ifstream cin("input.txt");
	__int64 n,m;
	vector <int> a,b;
	b.resize(2000000,-1);
	cin>>n>>m;
	a.resize(2*n);
	for (int i=0;i<n;i++)
	{
		cin>>a[i];
		a[i]--;
		a[n+i]=a[i];
	}
	__int64 q;
	for (int i=0;i<m;i++)
	{
		cin>>q;
		q--;
		b[q]=i;
	}
	__int64 res=0;
	__int64 l=-1;
	deque <__int64> qq;
	for (int r=0;r<2*n;r++)
	{
		if (b[a[r]]==-1)
		{
			l=-1;
			qq.clear();
			continue;
		}
		q=b[a[r]];
		if (!qq.empty())
		{
			while (q<qq.back()) q+=m;
			while (!qq.empty()&&(q-qq.front()>m))
				qq.pop_front();
		}
		qq.push_back(q);
		res=max<__int64> (res,qq.size());
	}
	cout<<res;
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#pragma warning( disable : 4244 4267 4018 4996 4800 )
//#pragma comment( linker, "/stack:10000000" )
using namespace std;
typedef vector< int > vi; typedef vector< vector< int > > vvi; typedef vector< string > vs; typedef vector< double > vd;
typedef vector< vd > vvd; typedef long long ll; typedef vector< ll > vll; typedef vector< vll > vvll; typedef pair< int, int > pii;
#define all( v ) (v).begin( ), (v).end( )

#ifdef LOCAL
ifstream in( "c.in" );
#else
istream & in = cin;
#endif
ostream & out = cout;

int main() {
    return 0;
}

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>

#define N 1000010

using namespace std;

int a[N * 2], b[N], h[N];
long long id[N];

int main()
{
    int n, m;
    while(cin >> n >> m) {
        for(int i = 0; i < n; ++i) {
            scanf("%d", a + i);
            //cin >> a[i];
            a[i + n] = a[i];
        }
        for(int i = 1; i < N; ++i) {
            h[i] = -1;
        }
        for(int i = 0; i < m; ++i) {
            scanf("%d", b + i);
            //cin >> b[i];
            h[b[i]] = i;
        }
        int left = -1, right = 0, ans = 0;
        while(right < 2 * n) {
            ++left;
            if(h[a[right]] == -1) {
                left = right = right + 1;
            }
            if(left > right) {
                puts("fuck");
            }
            while(right < 2 * n && h[a[right]] != -1) {
                if(left == right) {
                    id[right] = h[a[right]];
                } else {
                    id[right] = id[right - 1] + (h[a[right]] - h[a[right - 1]] + m) % m;
                }
                if(id[right] < id[left]) {
                    cout << left << ' ' << right << ' ' << id[left] << ' ' << id[right] << ' ';
                    puts("fuck");
                }
                if(id[right] - id[left] < m) {
                    ++right;
                } else {
                    break;
                }
            }
            ans = max(ans, right - left);
        }
        cout << ans << endl;
    }
    return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std ;
#define rep( i, j, k ) for( i = j ; i <= k ; ++i )
#define MaxL 1000015

struct node
{
	int v, fr ;
}br[MaxL], ar[MaxL] ;
int La, Lb, ans, h[MaxL << 1], pre[MaxL << 1] ;

inline bool cmp ( node a, node b )
{
	return ( a.v < b.v ) ;
}

int main()
{
	int i, j, l, r, mid ;

	scanf("%d%d",&La, &Lb) ;
	rep( i, 1, La )
	{
		scanf("%d", &ar[i].v) ;
		ar[i].fr = i ;
	}
	rep( i, 1, Lb )
	{
		scanf("%d", &br[i].v) ;
		br[i].fr = i ;
	}

	sort( br+1, br+1+Lb, cmp ) ;
	sort( ar+1, ar+1+La, cmp ) ;
	for( j = i = 1 ; i <= La ; ++i )
	{
		for( ; br[j].v < ar[i].v && j <= Lb ; ++j ) ;
		if( br[j].v == ar[i].v )
			h[ar[i].fr] = h[ar[i].fr+La] = br[j].fr ;
	}

	rep( i, 2, ( La << 1 ) )
		while( h[i] < h[i-1] )
			h[i] += Lb ;
	for( i = 2 ; i <= ( La << 1 ) ; ++i )
	{
		pre[i] = pre[i-1] ;
		if( h[i] > h[i-1] && h[i-1] ) ++pre[i] ;
	}

	for( i = 1 ; i <= La ; ++i ) // ö�����
	{
		if( !h[i] ) continue ;
		for( l = i, r = i + La - 1 ; l <= r ; ) // ������ ÿһ������ �� ���� ���һ�� - ��Сһ�� <= Lb
		{
			mid = ( l + r ) >> 1 ;
			if( pre[mid] - pre[i] == mid - i && h[mid] - h[i] < Lb )
				l = mid + 1 ;
			else
				r = mid - 1 ;
		}
		ans = max( ans, l-i ) ;
	}

	printf("%d\n",ans) ;
//	system("pause") ;
	return 0 ;
}

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>

#define N 1000010

using namespace std;

int a[N * 2], b[N], h[N];
long long id[N];

int main()
{
    int n, m;
    while(cin >> n >> m) {
        for(int i = 0; i < n; ++i) {
            scanf("%d", a + i);
            //cin >> a[i];
            a[i + n] = a[i];
        }
        for(int i = 1; i < N; ++i) {
            h[i] = -1;
        }
        for(int i = 0; i < m; ++i) {
            scanf("%d", b + i);
            //cin >> b[i];
            h[b[i]] = i;
        }
        int left = -1, right = 0, ans = 0;
        while(right < 2 * n) {
            ++left;
            if(h[a[right]] == -1) {
                left = right = right + 1;
            }
            while(right < 2 * n && h[a[right]] != -1) {
                if(left == right) {
                    id[right] = h[a[right]];
                } else {
                    id[right] = id[right - 1] + (h[a[right]] - h[a[right - 1]] + m) % m;
                }
                if(right - left < n && id[right] - id[left] < m) {
                    ++right;
                } else {
                    break;
                }
            }
            ans = max(ans, right - left);
        }
        cout << ans << endl;
    }
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <algorithm>

#define N 1100000
#define INF 2000000000000000000LL
#define MIN(x,y) ((x)<(y)?(x):(y))
#define MAX(x,y) ((x)>(y)?(x):(y))

int n, m, a[2*N], bi[N];

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    memset(bi, -1, sizeof(bi));
    for(int i = 0; i < m; i++) {
        int x;
        scanf("%d", &x);
        bi[x] = i;
    }
    for(int i = 0; i < n; i++) {
        a[i] = a[i+n] = bi[a[i]];
        //printf("%d%c", a[i], i<n-1?' ':'\n');
    }

    int lm = 0;
    int i = 0, j = 0;
    for(int i = 0; i < n; i++) {
        if(a[i] < 0) continue;
        if(i > j) j = i;
        if(a[i] <= a[j]) {
            while(a[j+1] >= a[j])
                ++j;
            if(a[j+1] >= 0 && a[j+1] < a[i])
                ++j;
            while(a[j+1] >= a[j] && a[j+1] < a[i])
                ++j;
        } else {
            while(a[j+1] >= a[j] && a[j+1] < a[i])
                ++j;
        }
        if(j - i + 1 > lm)
            lm = j - i + 1;
    }
    printf("%d\n", lm);
    return 0;
}

#include <cstdio>
using namespace std;
const int MAX_N = 1200005;
int N_A, N_B, top, buttom;
int A[MAX_N], B[MAX_N], pos[MAX_N];
long long queue[MAX_N + MAX_N];

int main()
{
    //freopen("nimo.in", "r", stdin);
    scanf("%d%d", &N_A, &N_B);
    for (int i = 1; i <= N_A; i++)
        scanf("%d", &A[i]);
    for (int i = 1; i <= N_B; i++)
        scanf("%d", &B[i]);

    for (int i = 1; i <= N_B; i++)
        pos[B[i]] = i;

    buttom = 1; top = 0;
    queue[0] = 0;
    int count = 0, ans = 0;
    for (int o = 1; o <= 2; o++)
    for (int i = 1; i <= N_A; i++)
    {
        if (o == 2 && i == N_A) break; // the final
        if (pos[A[i]] == 0)
        {
            top = buttom = 0;
            queue[0] = 0;
            count = 0;
            continue;
        }

        long long tmp = count * N_B + pos[A[i]];
        while (tmp <= queue[top])
        {
            count ++;
            tmp += N_B;
        }

        while (buttom <= top && queue[buttom] <= tmp - N_B) buttom++;
        queue[++top] = tmp;
        if (top - buttom + 1 > ans) ans = top - buttom + 1;
    }
    printf("%d\n", ans);
    return 0;
}

#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
using namespace std;

#define ll long long
#define sqr(a) (a) * (a)
#define S second
#define F first
#define m_p make_pair
#define p_b push_back

int main()
{
    ios_base::sync_with_stdio(false);
    string s;
    cin >> s;
    vector<int> split;
    for(int i = 0; i < s.length(); ++i)
            if(s[i] == '.')
                    split.push_back(i);
    if(split.size() == 0)
    {
                    cout << "NO";
                    return 0;
    }
    int prev = split[0];
    if(split[0] > 8) {
                cout << "NO";
                return 0;
    }
    for(int i = 1; i < split.size(); ++i)
    {
            if(split[i] - prev > 12  || split[i] - prev < 3)
            {
                        cout << "NO";
                        return 0;
            }
            prev = split[i];
    }
    if(s.length() - split.back() == 1 || s.length() - split.back() > 4) {
                  cout << "NO";
                  return 0;
    }
    cout << "YES" << endl;
    string cur;
    int i = 0;
    while(i < s.length())
    {
            cur = "";
            while(s[i] != '.')
            {
                       cur += s[i];
                        ++i;
            }
            int add = 0;
            while(i + add < s.length() && add <= 3 && !(i + add + 1 < s.length() && s[i + add + 1] == '.'))
            {
                      cur += s[i + add];
                      ++add;
            }
            i = i + add;
            cout << cur << endl;
    }

    cin >> s;

    return 0;
}

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <queue>
#include <math.h>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <bitset>
#include <list>
#include <ctype.h>
#include <cassert>
#include <stack>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <ctime>
#include <functional>
#include <ctime>

using namespace std;

#define snd second
#define fst first
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld double
#define pb push_back
#define left _left
#define right _right

const ld pi = 3.14159265359;

template<typename T>
T abs(T x) {
    return x > 0 ? x : -x;
}

template<typename T>
T sqr(T x) {
    return x * x;
}

template<typename T>
void chmin(T &x, T y) {
    x = min(x, y);
}

template<typename T>
void chmax(T &x, T y) {
    x = max(x, y);
}

template<typename U, typename V>
ostream &operator<<(ostream &s, const pair<U, V> &x) {
    s << "(" << x.fst << ", " << x.snd << ")";
    return s;
}

template<typename U>
ostream &operator<<(ostream &s, const vector<U> &x) {
    s << "[";
    bool was = false;
    for (auto it : x) {
        if (was) {
            s << ", ";
        }
        was = true;
        s << it;
    }
    s << "]";
    return s;
}

template<typename U>
ostream &operator<<(ostream &s, const set<U> &x) {
    s << "{";
    bool was = false;
    for (auto it : x) {
        if (was) {
            s << ", ";
        }
        was = true;
        s << it;
    }
    s << "}";
    return s;
}

template<int sz>
ostream operator << (ostream &s, const bitset<sz> &x) {
    for (int i = 0; i < sz; i++) {
        s << x[i];
    }
    return s;
}

//-----------------------------------------------------------------------------

const int maxn = 2e6 + 5;
int a[maxn], b[maxn];

int main() {
    srand(time(NULL));

    retry:

#ifdef LOCAL
    //gen();
    //cerr << 1 << endl;
    freopen("a.in", "r", stdin);
#else
    //freopen("fract.in", "r", stdin);
    //freopen("fract.out", "w", stdout);
#endif

    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
        a[n + i] = a[i];
    }

    fill(b, b + maxn, -1);

    for (int i = 0; i < m; i++) {
        int x;
        scanf("%d", &x);
        b[x] = i;
    }

    int ans = 0;
    deque<ll> q;

    for (int i = 0; i < n + n; i++) {
        if (q.empty()) {
            if (b[a[i]] != -1) {
                q.push_front(b[a[i]]);
            }

            chmax(ans, (int)q.size());
            continue;
        } else {
            ll x = q.front();
            ll y = b[a[i]];

            if (y == -1) {
                q.clear();
                continue;
            }

            if (y < x) {
                q.push_front(y + ((x / m) + 1) * m);
            } else {
                q.push_front(y);
            }

            while (q.front() - q.back() >= m) {
                q.pop_back();
            }

            chmax(ans, (int)q.size());
        }
    }

    cout << ans << endl;

    return 0;
}

#include <iostream>
#include <algorithm>
using namespace std;
#define lim 2000000

int n,m,i,j,x,s,e,mx;
int A[lim],I[lim],P[lim];

bool in(int x,int y,int z)
{
  if(z<y)
    z+=m;
  if(x<y)
    x+=m;
  return x>y && x<z;
}
int main()
{
  scanf("%d%d",&n,&m);
  for(i=0;i<n;i++)
  {
    scanf("%d",&A[i]);
    A[n+i]=A[i];
  }
  for(i=0;i<m;i++)
  {
    scanf("%d",&x);
    I[x]=i;
  }
  for(i=j=0;i<n;i++)
  {
    j=max(j,i);
    while(j-i<n)
    {
      x=I[A[j]];
      if(x==-1 || (e>s && in(x,P[s],P[e-1])))
        break;
      j++;
      P[e++]=x;
    }
    mx=max(mx,e-s);
    if(s<e)
      s++;
  }
  printf("%d",mx);
  return 0;
}

#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <deque>
#include <iostream>
#include <iomanip>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <string> vs;

#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define REP(i, a) for (int i = 0; i < (a); i++)
#define REPD(i, a) for (int i = ((a) - 1); i >= 0; i--)
#define FIT(it, v) for (typeof((v).begin())it = (v).begin(); it != (v).end(); ++it)
#define FITD(it, v) for (typeof((v).rbegin())it = (v).rbegin(); it != (v).rend(); ++it)

#define VAR(a, b) typeof(b) a(b)
#define ALL(v) (v).begin(), (v).end()
#define SET(a, x) memset((a), (x), sizeof(a))
#define SIZE(a) ((int)(a).size())

#define EXIST(a, b) (find(ALL(a), (b)) != (a).end())
#define SORT(x) sort(ALL(x))
#define GSORT(x) sort(ALL(x), greater<typeof(*((x).begin()))>())
#define UNIQUE(v) SORT(v); (v).resize(unique(ALL(v)) - (v).begin())
#define ENUM(v) FIT(it, (v)) cout << *it << " "; cout << endl

#define PF push_front
#define PB push_back
#define MP make_pair
#define F first
#define S second

const char IN[] = "_.in";
const char OUT[] = "_.out";
const int maxn=2010000;

int ntest = 0, test;
int n,m,res,l,r;
int a[maxn],b[maxn],vt[maxn];
void nhap()
{
    cin>>n>>m;
    FOR(i,1,n) cin>>a[i];
    FOR(j,1,m) cin>>b[j];

}

void init()
{

    FOR(i,n+1,n*2)
    {
        a[i]=a[i-n];
        vt[a[i]]=-1;
    }

    FOR(i,1,m)
    vt[b[i]]=i;
}

bool ok(int l,int r,int u)
{

    if (l<=r)
    {
        if (l<=u && u<=r) return 0; else return 1;
    }
    else
    {
        if (r<u && u<l) return 1; else return 0;
    }
    return 0;
}
void solve()
{
    res=0;
    l=1;
    r=0;

    while (r<=2*n)
    {
        if (vt[a[r+1]]!=-1 && ok(vt[a[l]],vt[a[r]],vt[a[r+1]]) )
        r++;
        else
        {
            res=max(res,r-l+1);
            while (vt[a[l+1]]==-1 && l+1<=n) l++;
            l++;
            if (l>n) break;
            if (r<l) r=l;

        }
    }

    cout<<res;

}
int main() {
  //  freopen(IN, "r", stdin);
  //freopen(OUT, "w", stdout);
  ios_base::sync_with_stdio(false);
    nhap();
    init();
    solve();
    return 0;
}

#pragma comment(linker, "/STACK:16777216")

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<utility>
#include<algorithm>
#include<list>
using namespace std;

#define pb push_back
#define MS( a ) memset( a,0,sizeof(a))
#define MSV( a,v ) memset( a,v,sizeof(v))

#define MAX 1000007

long l1,l2;
long s1[2*MAX+7];
long Ind[MAX+7];

bool Inside( long l,long r,long i )
{
	if( l<=r ){
		return i>=l && i<=r;
	}
	else{
		return i>=l || i<=r;
	}
}

int main( void )
{
    long i,j,v;

    cin>>l1>>l2;
    for( i=0;i<l1;i++ ){
		cin>>s1[i];
		s1[l1+i] = s1[i];
	}
	memset( Ind,-1,sizeof(Ind));
	for( i=0;i<l2;i++ ){
		cin>>v;
		Ind[v] = i;
	}

	long Lim = 2*l1;
	long qL,qR,qS = 0;
	long L = 0,R = l2-1;
	long Ans = 0;
	for( i=0;i<Lim;i++ ){
		if( Ind[s1[i]]==-1 ){
			qS = 0;
		}
		else if( !qS ){
			qL = qR = i;
			qS = 1;
		}
		else if( qS<l1 && Inside( L,R,Ind[s1[i]]) ){
			qR++;
			qR %= l1;
			qS++;
		}
		else{
			qR %= l1;
			qS--;
			i--;
		}
		if( qS ){
			L = (Ind[qR]+1)%l2;
			R = (Ind[qL]+l2)%l2;
		}
		//printf("Range  %ld %ld\n",L,R );
		Ans = max( Ans,qS );
		//cout<<q.size()<<endl<<endl;
		//cin>>v;
	}
	Ans = max( Ans,(long)qS );

	cout<<Ans<<endl;

	//cin>>i;

    return 0;
}

#include <iostream>
#include <vector>
#include <string>
#include <string.h>
#include <cmath>
#include <cstdio>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define FOR(i,a,b) for (int i = (a); (i) <= (b); (i)++)
using namespace std;
const int maxN = 1000005;

int n,m;
int a[maxN<<1],ind2[maxN];
int start,finish,len;

bool good(int ind)
{
    if (start == 0 && finish ==0) return true;
//  cout << "try " << start << " " << finish<< endl;
    if (start <= finish)
    {
        return (ind > finish || ind < start);
    }
    else
    {
        return (ind>finish && ind < start);
    }
}

int main()

{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    scanf("%d%d\n",&n,&m);
    FOR(i,1,n)
    {
        scanf("%d",&a[i]);
    }
    for (int i = n+1; i <= n+n; i++) a[i] = a[i-n];
    FOR(i,1,m)
    {
        int x;
        scanf("%d",&x);
        ind2[x] = i;
    }

    int maxans = 0;
    int last = 1;
    while (last <= n+n)
    {
        if (ind2[a[last]] == 0)
        {
            len = 0;
            start = finish = 0;
//          printf("last %d len = %d    start = %d  finish = %d\n",last, len, start, finish);
            last++;
            continue;
        }
        if (good(ind2[a[last]]))
        {
            finish = ind2[a[last]];
            len++;
            if (len == 1) start = finish;
            if (len > maxans) maxans = len;
        }
        else
        {
            int fn = ind2[a[last]];
            int k = len-1;
            while (!good(ind2[last]) && k>0)
            {
                start = ind2[a[last-k]];
                len--;
                k--;
            }
            len++;
            finish = fn;
        }
//      printf("last %d len = %d    start = %d  finish = %d\n",last, len, start, finish);
        last++;
        if (len == n)  break;
    }
    cout << maxans << endl;
    return 0;
}

#include<iostream>
#include<list>
#include<cstdio>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#include<bitset>
#pragma comment(linker, "/STACK:367721060")
using namespace std;
#define y1 stupid_cmath
const int MAX = 1e6 + 100;
const int modul = 1e9 + 7;

int mod(int x, int y) {
	return (x % y + y) % y;
}

int f(vector<int>a, vector<int>b)
{
	map<int, int> MAP;
	for (int i = 0; i < b.size(); i++)
	{
		MAP[b[i]] = i + 1;
	}

	int ans = 0;

	int x = 0;
	int y = 0;

	while (x < a.size())
	{
		if (MAP.count(a[y % a.size()]) == 0)
		{
			y++;
			x = y;
			continue;
		}
		else if (y != x && mod(MAP[a[y % a.size()]] - MAP[a[x % a.size()]], b.size()) < mod(MAP[a[y % a.size()]] - MAP[a[mod(y - 1, a.size())]], b.size()))
		{
			x++;
		}
		else
		{
			y++;
			ans = max(ans, (y - x) % (int)a.size());
		}
		//cout << x << " " << y << endl;
	}

	return ans;
}

int main()
{
	std::ios::sync_with_stdio(0);
	//freopen("INPUT.txt", "r", stdin);
	//freopen("OUTPUT.txt", "w", stdout);
	vector<int>a;
	vector<int>b;
	int la, lb;
	cin >> la >> lb;
	int tmp;
	for (int i = 0; i < la; i++)
	{
		cin >> tmp; a.push_back(tmp);
	}
	for (int i = 0; i < lb; i++)
	{
		cin >> tmp; b.push_back(tmp);
	}
	//cout << max(f(a, b), f(b, a)) << endl;
	cout << f(a, b) << endl;
	return 0;
}

#pragma comment(linker, "/STACK:60000000")
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <sstream>
#include <iomanip>
#include <complex>
#include <queue>
#include <functional>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) int(a.size() - 1)
#define all(a) a.begin(), a.end()
#define seta(a,x) memset (a, x, sizeof (a))
#define I (int)
#define next NEXTHUI
#define prev PREVHUI
#define y1 Y1HUI

typedef long long int64;
typedef pair <int, int> pii;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const int64 inf64 = ((int64)1 << 62) - 1;
const long double pi = 3.1415926535897932384626433832795;

template <class T> T sqr (T x) {return x * x;}

int n, m;
int a[2000000], b[1000000];
int f[1000001];
int64 Q[1001000];

int main ()
{
//	freopen ("input.txt", "r", stdin);
//	freopen ("output.txt", "w", stdout);
	cin >> n >> m;
	forn (i, n)
		scanf ("%d", &a[i]);
	forn (i, m)
		scanf ("%d", &b[i]);
	seta (f, 255);
	forn (i, m)
		f[b[i]] = i;
	int res = 0;
	int h, t;
	h = t = 0;
	forn (i, n)
		a[i+n] = a[i];
	forn (i, n)
		f[i+n] = f[i];
	res = 0;
	int64 add = 0;
	t = -1;
	for (int i = 0; i < n*2; i ++) {
		if (f[i] == -1) {
			h = 0;
			t = -1;
			add = 0;
		} else {
			t ++;
			Q[t] = f[i];
			if (h < t && f[i-1] >= f[i])
				add += m;
			Q[t] += add;
			while (Q[t] - Q[h] >= m)
				h ++;
			res = max (res, t - h + 1);
		}
	}
	cout << res << endl;
	return 0;
}

#pragma comment (linker, "/stack:64000000")
#define _CRT_SECURE_NO_DEPRECATE
#define _USE_MATH_DEFINES
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <cstdio>

using namespace std;

#define forn(i,n) for (int i = 0; i < (int)n; i++)
#define fore(i,a,b) for (int i = (int)a; i < (int)b; i++)
#define ford(i,n) for (int i = (int)n - 1; i >= 0; i--)
#define for1(i,n) for (int i = 1; i <= (int)n; i++)
#define mp make_pair
#define pb push_back
#define vi vector<int>
#define pii pair<int, int>
#define ll long long
#define ld long double
#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()
#define y1 goodlife

const int INF = 1000000000;
const ld EPS = 1E-9;

int n, m;

vi a, pos;

int q[2000000], l = -1, r = -1;

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    scanf("%d%d", &n, &m);
    a.resize(n);
    forn (i, n) {
        scanf("%d", &a[i]);
    }
    pos.assign(1000001, -1);
    forn (i, m) {
        int v;
        scanf("%d", &v);
        pos[v] = i;
    }
    int res = 0, cur = 0, j = 0;
    forn (i, n) {
        l++;
        cur--;
        if (l > r) {
            cur = 0;
            j = i;
            l = r + 1;
        }
        while (true) {
            int to = pos[a[j]];
            bool can = true;
            if (to == -1) {
                can = false;
            }
            else {
                if (l <= r) {
                    int st = q[l], fs = q[r];
                    if (st <= fs && to >= st && to <= fs)
                        can = false;
                    if (st > fs && (to >= fs || to <= st))
                        can = false;
                }
            }
            if (!can) {
                break;
            }
            else {
                cur++;
                res = max(res, cur);
                j = (j + 1) % n;
                q[++r] = to;
            }
        }
    }
    printf("%d", res);
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.14159265358979
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

using namespace std;
int a[2000010];
int b[1000010];
int pos[1000010];
int f[1000010];
int main()
{
	//freopen("in.txt","r",stdin);
	int res=0;
	int n,m;
	MEMS(pos,-1);
	scanf("%d%d",&n,&m);
	FOR(i,0,n)
	{
		scanf("%d",&a[i]);
		a[n+i]=a[i];
	}
	FOR(i,0,m)
	{
		scanf("%d",&b[i]);
		pos[b[i]]=i;
	}
	int l=0,r=0;
	int cur=0;
	while ((l<n+n)&& (pos[a[l]]==-1))
	{
		l++;
		r++;
	}
	while ((l<n+n) && (r<n+n-1))
	{
		if (r-l==n)
		{
			l++;
			cur^=f[l];
			continue;
		}
		res=max(res,r-l+1);
		if ((r+1<n+n) && (pos[a[r+1]]==-1))
		{
			while (l<r)
			{
				l++;
				cur^=f[l];
			}
			while ((r+1<n+n) && (pos[a[r+1]]==-1))
			{
				r++;
				l=r;
			}
			l++;
			r++;
			res=max(res,r-l+1);
			continue;
		}
		if (pos[a[r+1]]>=pos[a[r]])
		{
			if (cur)
			{
				if (pos[a[r+1]]<pos[l])
				{
					r++;
				}
				else
				{
					l++;
					cur^=f[l];
				}
			}
			else
				r++;
		}
		else
		{
			if (cur)
			{
				l++;
				cur^=f[l];
			}
			else
			{
				if (pos[a[r+1]]<pos[a[l]])
				{
					cur=1;
					r++;
					f[r]=1;
				}
				else
				{
					l++;
					cur^=f[l];
				}
			}
		}
	}
	cout<<res<<endl;
	return 0;
}

// Problem: B. Ancient Berland Hieroglyphs
// Contest: Codeforces - VK Cup 2012 Round 3
// URL: https://codeforces.com/contest/164/problem/B
// Memory Limit: 256 MB
// Time Limit: 1500 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e6 + 5;

int la, lb;
int a[N], b[N], p[N];

bool lil(int l, int i, int r) {
  if (l <= r) {
    return l <= i && i <= r;
  }
  return l <= i || i <= r;
}

int32_t main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> la >> lb;
  for (int i = 1; i <= la; ++i) {
    cin >> a[i];
    a[i + la] = a[i];
  }
  for (int i = 1; i <= lb; ++i) {
    cin >> b[i];
    p[b[i]] = i;
  }
  int ans = 0, j = 2;
  for (int i = 1; i <= la; ++i) {
    if (p[a[i]]) {
      if (j < i + 1) {
        j = i + 1;
      }
      while (j - i < la &&
        p[a[j]] &&
        !lil(p[a[i]], p[a[j]], p[a[j - 1]])) {
        ++j;
      }
      ans = max(ans, j - i);
    }
  }
  cout << ans;
}

#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <deque>

using namespace std;

const int N = 101010;
int n, m, ans;
int a[N], b[N], l, r, L, R;
map<int,int> where;

int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++) {
		cin >> b[i];
		where[b[i]] = i;
	}

	int size = 0;
	while (true) {
//		cout << l << " " << r << "    " << L << " " << R << "    " << size << endl;
		ans = max(ans, size);
		int next = where[a[r]];
		bool ok = false;

		if ((L < R || (L == R && !size)) && (next >= R || next < L))
			ok = true;
		if (L > R && (next >= R && next < L))
			ok = true;

		if (ok) {
			if (L == R)
				L = next;
			R = (next+1)%m;
			r = (r+1)%n;
			size++;
		} else {
			if (l == n-1)
				break;
			if (l == r)
				r = (r+1)%n;
			l = (l+1)%n;
			if (L != R)
				L = where[a[l]];
			size = max(size-1, 0);
		}
	}

	cout << ans << endl;

	return 0;
}

#include <cstdio>
#define len1 2000001
#define max(a,b) (a > b ? a : b )
#define oo 1000000000
int hash[len1] , link[len1] ;
int a[len1] , b[len1] ;
int n , m , ans = 0  ;

int main()
{
    int i , j , k ;
    int tk = 0 , bb ;

    scanf("%d%d",&n,&m);
    for ( i = 1 ; i<= n ; ++i )
        scanf("%d",a+i);
    for ( i = 1 ; i<= m ; ++i )
    {
        scanf("%d",b+i);
        hash[ b[i] ] = i ;
    }

    for ( i = 1 ; i <= n ; ++i)
        if ( hash[ a[i] ] )
            link[i] = hash[ a[i] ] ;

    for ( i = 1 ; i <= n ; ++i )
    {
        hash[ a[i] ] = 0 ;
        a[i+n] = a[i] ;
        link[i+n] = link[i] ;
    }

    bb = oo ;
    for ( j = i = 1 ; i <= 2*n ; ++i )
    {
        if ( link[i] == 0 )
        {
            while ( j <= i )
                ++j , hash[ a[j] ] = 0 ;
            continue ;
        }

        hash[ a[i] ] ++;

        if ( hash[ a[i] ] > 1 )
        {
            for ( j ; j < i ; ++j )
            {
                hash[ a[j] ] -- ;
            }
        }
        if ( i == j )
            tk = 0 , bb = oo  ;

        else
        {
            if ( link[i] > link[i-1] )
            {
                ;
            }
            else if ( tk == 0 )
            {
                tk = 1 ;
                bb = i ;
            }
            else
            {
                while ( j < bb )
                {
                    hash[ a[j] ] -- ;
                    ++j ;
                }
                bb = i ;
            }
        }

        if ( tk )
        {
            while ( link[i] > link[j] && j < i )
            {
                ++j ;
                hash[ a[j] ] -- ;
                if ( j >= bb )
                    tk = 0 , bb = oo ;
            }
        }
        ans = max ( ans , i-j+1 ) ;
    }

    printf("%d\n",ans);
    return 0;
}

/*
* Problem:
* Author: Leo Yu
* Time:
* State:
* Memo:
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
inline int   read()
{
	int x = 0;	char ch = getchar();	bool positive = 1;
	for (; ch < '0' || ch > '9'; ch = getchar())  if (ch == '-')  positive = 0;
	for (; ch >= '0' && ch <= '9'; ch = getchar())    x = x * 10 + ch - '0';
	return positive ? x : -x;
}
#define link Link
#define next Next

int N, M, a[2000006], pos[2000006];

bool	in_segment(int l, int r, int x)
{
	if (l <= r)	return x >= l && x <= r;
	return x >= r || x <= l;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif

	N = read(), M = read();
	for (int i = 1; i <= N; ++ i)	a[i] = a[i + N] = read();
	for (int j = 1; j <= M; ++ j)	pos[read()] = j;
	int l = 0, r = 0;
	int ans = 0;
	for (int i = 1, j = 1; i <= N; ++ i)	if (pos[a[i]])
	{
		l = pos[a[i]];
		if (j <= i)	j = i + 1, r = pos[a[i]];
		while (j < i + N && pos[a[j]] && !in_segment(l, r, pos[a[j]]))	r = pos[a[j ++]];
		ans = max(ans, j - i);
	}
	cout << ans << endl;

	return 0;
}

#include<cmath>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<sstream>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<time.h>
#include<stdlib.h>
#include<assert.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define rep(i,l,r) for(int i=(l);i<(r);++i)
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e6 + 7;
const int INF = 1e9 + 7;
const int MOD = 1e9 + 7;
const double Pi = acos(-1.0);
const double EPS = 1e-8;
//--------head--------
int n, m, a[N << 1];
map<int, int> R;
int get(int v) {
	if (R.find(v) == R.end())
		return -1;
	return R[v];
}
void clear(queue<int> &que) {
	while (!que.empty())
		que.pop();
}
int main() {
	scanf("%d%d", &n, &m);
	rep(i, 0, n)
		scanf("%d", a + i);
	rep(i, 0, m) {
		int x;
		scanf("%d", &x);
		R[x] = i;
	}
	rep(i, 0, n)
		a[i] = a[n + i] = get(a[i]);
	a[n << 1] = -1;
//	rep(i, 0, 2 * n) printf("%d ", a[i]);puts("");
	int ans = 0;
	for (int i = 0; i < n; ++i) {
		if (a[i] == -1)
			continue;
		int j, t = 0;
		queue<int> q[2];
		q[t].push(a[i]);
		for (j = i + 1; ~a[j]; ++j) {
			if (a[j] < q[t].back()) {
				if (t == 1) {
					swap(q[0], q[1]);
					clear(q[1]);
					t = 0;
				}
				t = 1;
				while (!q[0].empty() && q[0].front() < a[j])
					q[0].pop();
				q[t].push(a[j]);
			} else {
				if (t == 1)
					while (!q[0].empty() && q[0].front() < a[j])
						q[0].pop();
				q[t].push(a[j]);
			}
			ans = max(ans, sz(q[0]) + sz(q[1]));
		}
		i = j - 1;
	}
	printf("%d", ans);
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int n, m;
int x[2000100], y[1000100], p[1000100];

void init()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", &x[i]);
        x[i+n] = x[i];
    }
    memset(p, 0, sizeof(p));
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d", &y[i]);
        p[y[i]] = i;
    }
}

int ans = 0;

void work()
{
    int j = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (!p[x[i]]) continue;
        if (i > 1 && p[x[i+1]]) j = max(j, i + 2);
        else j = i + 1;
        while (j - i < n && p[x[j]] && ((p[x[i]] < p[x[j-1]] && !(p[x[j]] < p[x[j-1]] && p[x[j]] > p[x[i]])) || (p[x[j]] > p[x[j-1]] && p[x[i]] > p[x[j]])))
            ++j;
        ans = max(ans, j - i);
    }
    printf("%d\n", ans);
}

int main()
{
    init();
    work();
    return 0;
}

#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6 + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int a[maxn],b[maxn],where[maxn],where2[maxn];
int nxt[21][maxn],increase[21][maxn];
int32_t main()
{
    int n = in() , m = in();
    read(a,n) , read(b,m);
    memset(where,-1,sizeof where);
    memset(where2,-1,sizeof where2);
    for (int i = 0 ; i < n ; i++) where[a[i]] = i;
    for (int i = 0 ; i < m ; i ++) where2[b[i]] = i ;
    memset(nxt,-1,sizeof nxt);
    for (int lg = 0 ; (1 << lg) <= min(n,m) ; lg ++){
        for (int i = 0 ; i < m ; i++){
            if (where[b[i]] == -1)
                nxt[lg][i] = -1;
            else{
                if (lg == 0 ){
                    nxt[lg][i] = where2[a[(where[b[i]] + 1)%n]] , increase[lg][i] = nxt[lg][i] > i;
                    //cout << nxt[lg][i] << " ";
                }

                else{
                    int F = nxt[lg - 1][i];
                    if (F == -1) nxt[lg][i] = -1;
                    else nxt[lg][i] = nxt[lg-1][nxt[lg-1][i]] , increase[lg][i] = increase[lg-1][i] && nxt[0][nxt[lg - 1][i]] > nxt[lg-1][i] && increase[lg-1][nxt[lg-1][i]];
//                    cout << nxt[lg][i] << " ";
                }
            }
        }
        //cout << "\n";
    }
    int res = 0 ;
    for (int i = 0 ; i < m ; i++){
        if (where[b[i]] == -1) continue;
        int cur = i ;
        int current = 1 ;
        for (int lg = 20 ; lg >= 0 ; lg --){
            if (nxt[lg][cur] == -1 || !increase[lg][cur]) continue;
            cur = nxt[lg][cur];
            current += (1 << lg);
        }
        if (nxt[0][cur] == -1 || nxt[0][cur] >= i ) {
            res = max(res,current);
            continue;
        }
        cur = nxt[0][cur];
        current ++;
        for (int lg = 20 ; lg >= 0 ; lg --)
        {
            if (nxt[lg][cur] == -1 || !increase[lg][cur] || nxt[lg][cur] >= i) continue;
            if (nxt[lg][cur] == -1 || !increase[lg][cur]) continue;
        }
        res = max(res,current);

    }
    cout << res << endl;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;

const int maxn = 1000002;
int a[maxn*2], b[maxn*2], v[maxn];

int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n, m;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; ++i)
		scanf("%d", &a[i]), a[i + n] = a[i];
	for(int i = 0; i < m; ++i)
		scanf("%d", &b[i]), b[i + m] = b[i];
	for(int i = 0; i < maxn; ++i)
		v[i] = -1;
	for(int i = 0; i < m; ++i)
		v[b[i]] = i;
	int p = 0, t = 0, ans = 0;
	for(int i = 0; i < n; ++i)
	{
		if(p <= i) p = i, t = 0;
		if(t == 0)
		{
			while(p - i + 1 <= n && v[a[p+1]] > v[a[p]] && v[a[p+1]] - v[a[i]] + 1 <= m)
				++p;
			if(p-i+1 <= n && v[a[p+1]] != -1 && v[a[p+1]] < v[a[p]] && v[a[p+1]] - v[a[i]] + 1 <= 0)
				t = 1, p++;
		}
		if(t > 0)
		{
			while(p - i + 1 <= n && v[a[p+1]] > v[a[p]] && v[a[p+1]] - v[a[i]] + 1 <= 0)
				++p;
		}
		if(v[a[i]] != -1)
			ans = max(ans, p - i + 1);
	}
	cout << ans;

	return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <memory.h>

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.14159265358979
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

using namespace std;
int a[2000010];
int b[1000010];
int pos[1000010];
int f[1000010];
LL q[2000100];
int main()
{
	//freopen("in.txt","r",stdin);
	int res=0;
	int n,m;
	MEMS(pos,-1);
	scanf("%d%d",&n,&m);
	FOR(i,0,n)
	{
		scanf("%d",&a[i]);
		a[n+i]=a[i];
	}
	FOR(i,0,m)
	{
		scanf("%d",&b[i]);
		pos[b[i]]=i;
	}
	int l=0,r=0;
	FOR(i,0,n+n)
	{
		res=MAX(res,r-l+1);
		if (pos[a[i]]==-1)
			l=r+1;
		else
		{
			LL v=pos[a[i]];
			if (r-l+1==0)
			{
				r++;
				q[r]=v;
				continue;
			}
			LL last=q[r];
			if (v<last)
			{
				LL k=(last-v)/m;
				v+=(k+1)*m;
			}
			while ((r-l+1) && (v-q[l]>=m))
				l++;
			q[++r]=v;
		}
		if (r-l+1>n)
			l++;
	}
	res=MAX(res,r-l+1);
	cout<<res<<endl;
	return 0;
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#pragma warning( disable : 4244 4267 4018 4996 4800 )
//#pragma comment( linker, "/stack:10000000" )
using namespace std;
typedef vector< int > vi; typedef vector< vector< int > > vvi; typedef vector< string > vs; typedef vector< double > vd;
typedef vector< vd > vvd; typedef long long ll; typedef vector< ll > vll; typedef vector< vll > vvll; typedef pair< int, int > pii;
#define all( v ) (v).begin( ), (v).end( )

#ifdef LOCAL
ifstream in( "c.in" );
#else
istream & in = cin;
#endif
ostream & out = cout;

int main() {
    return 0;
}

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#define INF  1e9
#define SIZE 1000001
using namespace std;
int na[SIZE],nb[SIZE];
int posA[SIZE], posB[SIZE];
int main()
{
    int na1,nb1,i;

    while(scanf("%d %d",&na1,&nb1)==2)
    {
        memset(posB,-1,sizeof(posB));

        for(i = 0 ;i < na1; i++)
        {
            scanf("%d",&na[i]);
        }

        for(i = 0 ;i < nb1 ; i++)
        {
            scanf("%d",&nb[i]);
            posB[ nb[i] ] = i;
        }
        for(i = 0 ;i < 2*na1- 1 ; i++)
        {
            if(i < na1)
                posA[i] = posB[ na[i] ];
            else
            {
                posA[i] = posB[ na[i-na1] ]; //if( posA[i]!=-1)posA[i]+=nb1;
            }
          //  cout<<"pos "<<i << " : "<< posA[i]<<endl;
        }

        int len = 0;
        int ptr1,ptr2;
        ptr1 = ptr2 = 0;
        bool wrap = false;
        while(ptr2 < 2*na1-1)
        {
          //  cout<<ptr1<<' '<<ptr2<<endl;
//            cout<<ptr2<<endl;
            int c,p;
            if(ptr1== ptr2)
            {
                wrap = false;
                 c =   posA[ ptr2 ] ;
                 ptr2++;
                 if(c!=-1)
                    len = max(len,1);
                 else
                    ptr1++;
            }
            else
            {
                c =   posA[ptr2 ] ;
                p =   posA[ptr2-1];

                  if(c == -1 || p == -1)ptr1++;
                  else
                  {
                       if(wrap)
                       {
                           if( p < c && c < posA[ptr1])
                           {
                                len = max(len,ptr2 - ptr1+1);
                                ptr2++;
                           }
                           else ptr1++;
                       }
                       else
                       {
                           if(p> c)
                           {
                                wrap = true;
                                if(c >= posA[ptr1]){ptr1++;continue;}
                           }
                            len = max(len,ptr2 - ptr1+1);
                            ptr2++;
                       }
                   }
            }
            //cout<<"cur len : "<<len<<endl;
        }
        cout<<len<<endl;

    }
    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
using namespace std;

int m1[2000005];
int m2[2000005];
int pos1[1000005];
int pos2[1000005];
int ans[2000005];
int parent[2000005];
int n1, n2;

int main()
{
//  memset(ans, -1, sizeof(ans));
    scanf("%d%d", &n1, &n2);
    int i;
    for(i = 1; i <= n1; i++)
    {
        scanf("%d", m1 + i);
        m1[n1 + i] = m1[i];
        pos1[m1[i]] = i;
    }
    for(i = 1; i <= n2; i++)
    {
        scanf("%d", m2 + i);
        m2[n2 + i] = m2[i];
        pos2[m2[i]] = i;
    }
    int res = 0;
    int st = 1;
    for(i = 1; i <= n1 + n1; i++)
    {
        int p2 = pos2[m1[i]];
        int t = 0;
        if(p2)
        {
            t = 1;
            st = i;
            parent[i] = p2;
            if(ans[i - 1])
            {
                while(parent[i - 1] > p2)
                {
                    p2 += n2;
                }
                while(st < i && p2 - parent[st] + 1 > n2) st++;
                t = i - st + 1;
                parent[i] = p2;
            }
        }
        ans[i] = t;
//      cout << ans[i] << ' ' << parent[i] << endl;
        if(ans[i] > res) res = ans[i];
    }
    printf("%d\n", res);
    return 0;
}

#include <iostream>
#include <vector>
#include <string>
#include <string.h>
#include <cmath>
#include <cstdio>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define FOR(i,a,b) for (int i = (a); (i) <= (b); (i)++)
using namespace std;
const int maxN = 1000005;

int n,m;
int a[maxN<<1],ind2[maxN];
int start,finish,len;

bool good(int ind)
{
    if (start == 0 && finish ==0) return true;
//  cout << "try " << start << " " << finish<< endl;
    if (start <= finish)
    {
        return (ind > finish || ind < start);
    }
    else
    {
        return (ind>finish && ind < start);
    }
}

int main()

{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    scanf("%d%d\n",&n,&m);
    FOR(i,1,n)
    {
        scanf("%d",&a[i]);
        a[i+n] = a[i];
    }
    FOR(i,1,m)
    {
        int x;
        scanf("%d",&x);
        ind2[x] = i;
    }
    int maxans = 0,len = 0;
    start = finish = 0;
    int r = n+n;
    FOR(last,1,r)
    {
        a[last] = ind2[a[last]];
        cout << a[last]<< endl;
        if (a[last] == 0)
        {
            len = 0;
            start = finish = 0;
            continue;
        }
        while (!good(a[last]) && len > 0)
        {
            len--;
            start = a[last-len];
        }
        finish = a[last];
        len++;
        if (len == 1) start = finish;
        if (len > maxans) maxans = len;
//      printf("pos = %d  len = %d  start = %d  finish = %d\n",last, len,start,finish);
    }
    cout << maxans << endl;
    return 0;
}

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int a[1 << 20], b[1 << 20];

int aPlace[1 << 20], mp[1 << 20], N, M;

void scan(){
    scanf ( "%d%d", &N, &M );
    memset ( mp, -1, sizeof ( mp ) );

    for ( int i = 0; i < N; ++i ){
        scanf ( "%d", a + i );
        aPlace[ a[i] ] = i;
    }
    for ( int i = 0; i < M; ++i ){
        scanf ( "%d", b + i );
        mp[ b[i] ] = i;
    }

}

int valid ( int mid, int l2, int l1 ){
    if ( l1 == -1 || l2 == - 1) return 0;
    if ( mid < l2 && mid < l1 && l2 < l1 ) return 0;
    if ( mid > l1 && mid < l2 ) return 0;
    if ( l1 < mid && l2 < l1 ) return 0;
    if ( mid == l2 ) return 0;
    return 1;
}
void solve(){
    int l = -1, r = 0;;

    int mxans = 0;

    for ( int i = N; i < 3 * N; ++i )
        a[i] = a[i % N];

    while ( l < N - 1 ){
        ++l;
        if ( mp[ a[l + 1] ] == -1 || mp[ a[l] ] == -1 ) continue;
        if ( mp[ a[l] ] != -1 ) mxans = max ( mxans, 1 );
        r = max ( r, l + 2 );

        while ( valid ( mp[ a[l] ], mp[a[r]], mp[a[r - 1]] ) ){
            ++r;
        //    cout << mp[ a[l]] << " " << mp[a[r]] << " " << mp[a[r - 1] ] << " " << l << " " << r <<  " " << r - 1 << endl;
        }

        mxans = max ( mxans, r - l );
     //   cout << l << " " << r << endl;

    }

    printf ( "%d\n", min ( mxans, N ) );
}

int main(){
    scan();
    solve();
}

/* -*- coding: utf-8 -*-
 *
 * 0164B.cc: B. Ancient Berland Hieroglyphs
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

const int MAX_N = 1000000;
const int MAX_N2 = MAX_N * 2;
const int MAX_M = 1000000;

/* typedef */

typedef long long ll;
typedef pair<int,int> pii;

/* global variables */

int as[MAX_N];
ll bjs[MAX_N];
pii bs[MAX_M];

/* subroutines */

/* main */

int main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  int n, m;
  scanf("%d%d", &n, &m);

  for (int i = 0; i < n; i++) scanf("%d", as + i);
  for (int i = 0; i < m; i++) scanf("%d", &bs[i].first), bs[i].second = i;
  sort(bs, bs + m);

  for (int i = 0; i < n; i++) {
    int k = lower_bound(bs, bs + m, pii(as[i], 0)) - bs;
    bjs[i] = bjs[i + n] = (k >= m || bs[k].first != as[i]) ? -1 : bs[k].second;
  }

  int n2 = n * 2;
  ll pj = 0;
  for (int i = 0; i < n2; i++) {
    if (bjs[i] < 0) pj = 0;
    else {
      if (pj > bjs[i]) bjs[i] += (pj - bjs[i] + m - 1) / m * m;
      pj = bjs[i];
    }
  }

  int maxl = 0;
  for (int i = 0, j = 0; i < n2; i++) {
    if (bjs[i] < 0) j = i + 1;
    else {
      while (j < n2 && bjs[j] >= 0 && bjs[i] + m >= bjs[j]) j++;
      int l = j - i;
      //printf("i=%d, j=%d\n", i, j);
      if (maxl < l) maxl = l;
      if (maxl >= m) break;
    }
  }

  printf("%d\n", maxl);
  return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
using namespace std;

#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define forit(it,S) for(typeof(S.begin()) it = S.begin(); it != S.end(); ++it)

const int maxn = 1000000;
int a[maxn + 100], b[maxn + 100];
int n, m;
int pos[maxn + 100];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i)
		scanf("%d", &a[i]);

	memset(pos, -1, sizeof(pos));
	for (int i = 0; i < m; ++i) {
		scanf("%d", &b[i]);
		pos[b[i]] = i;
	}

	int res = 0;
	int k = 0;
	for (int i = 0; i < n; ++i) {
		int first = pos[a[i]];
		if (first == -1) {
			k = 0;
			continue;
		}
		k = max(k - 1, 1);
		int j = (i + k - 1) % n;
		int sum = (pos[a[j]] - pos[a[i]] + m) % m;

		while (true) {
			int jj = (i + k) % n;
			if (pos[a[jj]] == -1) break;
			sum += (pos[a[jj]] - pos[a[j]] + m) % m;
			if (sum > m) break;
			j = jj;
			++k;
		}
		res = max(res, k);
	}
	cout << res << endl;
	return 0;
}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <utility>
#include <vector>
#include <set>
#include <algorithm>

#define maxn 1000010
#define Fup(i, s, t) for (int i = s; i <= t; i ++)
#define Fdn(i, s, t) for (int i = s; i >= t; i --)
#define Path(i, s) for (int i = s; i; i = d[i].next)

using namespace std;

int x[maxn * 2], pos[maxn];
int l1, l2;

void init()
{
    cin >> l1 >> l2;
    Fup(i, 1, l1)
        cin >> x[i];
    Fup(i, l1 + 1, l1 + l1)
        x[i] = x[i - l1];
    Fup(i, 1, l2){
        int t;
        cin >> t;
        pos[t] = i;
    }
}

void solve()
{
    int head = 1, mid, tail = 1, ans = 0, t = 0;
    while (head <= l1){
        while (pos[x[tail]] == 0){
            ans = max(ans, tail - head);
            head = tail = tail + 1;
            t = 0;
        }
        if (t == 0){
            while (pos[x[tail]] < pos[x[tail + 1]])
                tail ++;
            if (pos[x[tail + 1]] < pos[x[head]]){
                tail ++;
                t ++;
                mid = tail;
                ans = max(ans, tail - head + 1);
            }else{
                ans = max(ans, tail - head + 1);
                head = tail = tail + 1;
                t = 0;
            }
        }else{
            while (head < mid && pos[x[tail]] < pos[x[tail + 1]]){
                if (pos[x[tail + 1]] < pos[x[head]]){
                    tail ++;
                    ans = max(ans, tail - head + 1);
                }else
                    while (head < mid && pos[x[tail + 1]] >= pos[x[head]])
                        head ++;
            }
            t = 0;
            head = mid;
        }
    }
    cout << ans << endl;
}

int main()
{
//    freopen("temp.in", "r", stdin);
//    freopen("temp.out", "w", stdout);
    ios::sync_with_stdio(false);
    init();
    solve();
    return 0;
}

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <map>
#include <algorithm>

#define mod 1000000007
#define inf 2000000000
#define forn(var, size) for(int var = 0; var < (int)(size); ++var)

using namespace std;

typedef vector<int> vi;
typedef vector< vector<int> > vvi;
typedef vector<bool> vb;
typedef pair<int, int> ii;

int a[1000500];
int b[1000500];
int c[1000500];
int q[2000500];

int main(int argc, char **argv) {
	int la, lb;
	scanf("%d %d", &la, &lb);
	forn(i, la)
		scanf("%d", a + i);
	forn(i, lb) {
		scanf("%d", b + i);
		c[b[i]] = i + 1;
	}
	int sz = 0;
	int qs = 1000010;
	int qe = qs;
	int curs = c[a[la - 1]];
	int curm = lb + 1;
	if(curs)
	for(int k = la - 1; k >= 0; k--) {
		int dig = a[k];
		int cp = c[dig] - curs;
		if(cp <= 0)
			cp += lb;
		if(k == la - 1)
			curs = cp;
//		cout << a[k] << " " << cp << " " << curm << endl;
		if(c[dig] && cp < curm) {
			sz++;
			curm = cp;
			q[--qs] = cp;
		} else
			break;
	}
	int ans = sz;
	for(int i = 0; i < la; i++) {
		if(c[a[i]]) {
			int cp = c[a[i]] - curs;
			while(cp <= 0)
				cp += lb;
			curs += cp;
			q[qe++] = curs;
			while(qs < qe && q[qs] <= curs - lb)
				qs++;
//			cout << a[i] << ": " << cp << ' ' << curs << ' ' << qs << ' ' << qe << endl;
		} else {
			qs = qe = 1000010;
		}
		ans = max(ans, qe - qs);
	}
	cout << ans << endl;
	return 0;
}

/*
 * in the name of god
 *
 *
 *
 *
 *
 *
 *
 */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <complex>
#include <stack>
#include <deque>
#include <queue>
#include <iomanip>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef complex<double> point;
typedef long double ldb;

const int maxN = 1000 * 1000 + 10;

int n,m;
int pos[maxN],a[maxN],b[maxN];
map <int,int> mp;

int mod (int x, int m){
	while (x>=m) x-=m;
	return x;
}

bool range (const int &l, const int &h, const int &x){
	return x>=l && x<=h;
}

int main(){

	scanf ("%d%d" , &n, &m);
	for (int i=0; i<n; i++) scanf("%d" , &a[i]);
	for (int i=0; i<m; i++) { scanf("%d" , &b[i]); mp[b[i]] = i; }

	for (int i=0; i<n; i++){
		if (mp.find(a[i])==mp.end())
			pos[i] = -1;
		else
			pos[i] = mp[a[i]];
	}

	int poi=-1 , ans = 0;

	for (int i=0; i<n && ans<min(n,m); i++){

		if (pos[i]==-1){
			poi = -1;
			continue;
		}

		if (poi==-1)
			poi=i;

		int lo1 = pos[i]+1 , hi1 = m-1;
		int lo2 = 0 , hi2 = pos[i]-1;

		if (poi!=i){
			if (range(lo1,hi1,pos[poi])) lo1 = pos[poi] + 1;
			else if (range(lo2,hi2,pos[poi])) { lo2 = pos[poi] + 1; hi1=-1,lo1=0; }
		}

		while (true){

			poi = (poi + 1) % n;

			if (poi==i){
				ans = n;
				break;
			}

			bool f = false;

			if (range(lo1,hi1,pos[poi])) { lo1 = pos[poi] + 1; f = true; }
			else if (range(lo2,hi2,pos[poi])) { lo2 = pos[poi] + 1; f = true; hi1=-1; lo1=0; }

			if (!f || pos[poi]==-1){
				poi = (poi-1+n)%n;
				break;
			}

		}

		if (poi<i)
			ans = max(ans , (n-i) + poi + 1);
		else if (poi>i)
			ans = max(ans , (poi-i+1));
	}

	printf ("%d\n" , ans);

	return 0;
}

/*
 * File: B.cpp
 * Author: wym510
 * Email: <wym6110@gmail.com>
 * Create Date: 2012-4-8 23:33:01
*/

#include <vector>
#include <string>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define S size()
#define B begin()
#define E end()
#define P push_back
#define fu(i,a,b) for(int i=a;i<b;++i)
#define fd(i,a,b) for(int i=b-1;i>=a;--i)
typedef long long int64;
using namespace std;

const int MaxN=3200000;
const int MaxM=3200000;
const int MaxNum=3200000;

int va[MaxN],vb[MaxM];
int pos[MaxNum];
int q[MaxN*2];

int main()
{
    int n,m;

    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",va+i);
    for(int i=1;i<=n;i++) va[i+n]=va[i];
    for(int i=1;i<=m;i++)
    {
        scanf("%d",vb+i);
        pos[vb[i]]=i;
    }

    int ans=0,ff=0,rr=0;

    for(int i=1,j=1;i<=2*n;i++)
    {
        while(1)
        {
            if(pos[va[j]]==0) break;

            int kk=pos[va[j]];

            if(ff==rr) q[rr++]=kk;
            else
            {
                kk+=(q[rr-1]/n)*n;
                if(q[rr-1]>kk) kk+=n;
                if(kk-q[ff]>=n) break;
                q[rr++]=kk;
            }
            j++;
        }
        ans=max(ans,j-i);
        if(ff<rr) ff++;
        if(i==j) j++;
    }

    cout<<ans<<endl;
    return 0;
}

/* vim: set ts=4 sw=4: */

#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<map>
#include<numeric>
#include<sstream>
#include<cmath>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i,x,y) for(int i = x; i<y; i++ )
#define FORV(it,A) for(vector<int>::iterator it = A.begin(); it!= A.end(); it++)
#define FORS(it,A) for(set<int>::iterator it = A.begin(); it!= A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
#define N 1100000
int a[N];
int perm[N], v[N];
int prox[N];
int n, m;

int diff (int x, int y){
    if (x == -1 || y == -1) return 0;
    if (x <= y) return y-x;
    return diff (0, y) + diff (x, m-1)+1;
}

int diff2 (int x, int y){
    if (x <= y) return y-x;
    return diff2 (0, y) + diff2 (x, n-1)+1;
}

int main (){
   scanf("%d %d", &n, &m);
   f (i, 0, n) prox[i] = i+1; prox[n-1] = 0;
   clr (perm, -1);
   f (i, 0, n) scanf("%d", &a[i]);
   f (i, 0, m){
       int x; scanf("%d", &x);
       perm[x] = i;
   }
   f (i, 0, n) v[i] = perm[a[i]];
   int ini, fim, andou, ans;
   fim = ini = fim = ans = andou = 0;
   //f (i, 0, n) printf("%d ", v[i]);
   //printf("\n");
   int vezes = 3*(max(n,m));
   while (vezes--){
       //printf("ini = %d fim = %d andou = %d\n", ini, fim, andou);
       if (v[fim] == -1){
           fim = prox[fim], ini = fim; continue;
       }
       if (andou == 0){
           ans = max (ans, 1);
           andou += diff (v[fim], v[prox[fim]]);
           fim = prox[fim]; continue;
       }
       if (andou >= m){
           andou -= diff (v[ini], v[prox[ini]]); ini = prox[ini];
       }
       else{
           ans = max (ans, diff2 (ini, fim)+1);
           andou += diff (v[fim], v[prox[fim]]);
           fim = prox[fim];
       }
   }
   printf("%d\n", ans);

   return 0;
}

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>

#define MAXN 1000010

using namespace std;

int a[MAXN * 2], b[MAXN], h[MAXN];
long long id[MAXN];

int next() {
    int x;
    scanf("%d", &x);
    if(x <= 0 || x > 1000000) {
        puts("fuck");
    }
    return x;
}

int main()
{
    int n, m;
    while(cin >> n >> m) {
        for(int i = 0; i < n; ++i) {
            //cin >> a[i];
            a[i + n] = a[i] = next();
        }
        for(int i = 0; i < MAXN; ++i) {
            h[i] = -1;
        }
        for(int i = 0; i < m; ++i) {
            b[i] = next();
            //cin >> b[i];
            h[b[i]] = i;
        }
        int left = -1, right = 0, ans = 0;
        while(right < 2 * n) {
            ++left;
            if(h[a[right]] == -1) {
                left = right = right + 1;
            }
            if(left > right) {
                puts("fuck");
            }
            while(right < 2 * n && h[a[right]] != -1) {
                if(left == right) {
                    id[right] = h[a[right]];
                } else {
                    id[right] = id[right - 1] + (m + h[a[right]] - h[a[right - 1]]) % m;
                    if(id[right] < id[right - 1]) {
                        cout << a[right - 1] << ' ' << a[right] << ' ' << h[a[right]] << ' ' <<  h[a[right - 1]] << endl;
                    }
                }
                //if(left > right || id[right] < id[left]) {
                //  cout << left << ' ' << right << ' ' << id[left] << ' ' << id[right] << endl;
                //}
                if(id[right] - id[left] < m) {
                    ++right;
                } else {
                    break;
                }
            }
            ans = max(ans, right - left);
        }
        cout << ans << endl;
    }
    return 0;
}

#include <string>
#include <vector>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<deque>
#include<numeric>
#include<list>
#include<cstdio>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#define REP(num,num2) for(int num=0;num<(int)num2;++num)
#define REPN(num,num2,init) for(int num=init;num<(int)num2;++num)
#define ITR(x) __typeof((x).begin())
#define FOR(itr,data) for(ITR(data) itr=(data).begin();itr!=(data).end();++itr)
#define ALL(typ) (typ).begin(),(typ).end()
#define SPR(x) ((x)*(x))
#define pb push_back
#define mp make_pair
#define fr first
#define sc second
#define sz size()
#define INF ((int)1e9)
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define prl cerr<<"called:"<< __LINE__<<endl;
using namespace std;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
typedef long long int lint;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<pair<int,int> > vp;
typedef pair<int,int> pi;
const double PI  = acos(-1.0);
template<class T> void debug(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T& a,const T& b) { if(a>b) a=b; }
template<class T> void chmax(T& a,const T& b) { if(a<b) a=b; }
int a[1000005],b[1000005];
int match[2000005];
pi sa[1000005],sb[1000005];
int main(){
	int n,m;scanf("%d%d",&n,&m);
	REP(i,n) scanf("%d",&a[i]),sa[i]=mp(a[i],i);
	REP(i,m) scanf("%d",&b[i]),sb[i]=mp(b[i],i);
	sort(sa,sa+n);
	sort(sb,sb+m);

	REP(i,n){
		int p=lower_bound(sb,sb+m,mp(a[i],-1))-sb;
		if(p<m && sb[p].fr==a[i]) match[i]=sb[p].sc;
		else match[i]=-1;
	}
	REP(i,n) match[i+n]=match[i];

	int begin=-1,end=-1;
	int res=0,begin2=-1;
	REP(i,n*2){
		if(match[i]==-1){
			begin2=-1;
			continue;
		}
		if(begin2==-1){
			end=begin=match[i];
			begin2=i;
			res=max(res,1);
			continue;
		}

		if(begin<=end){
			if(end<match[i]){
				end=match[i];
			}else{
				while(begin2<i && match[begin2]<=match[i]){
					++begin2;
				}
				begin=match[begin2];
				end=match[i];
			}
		}else{
			if(end<match[i]){
				while(begin2<i && match[begin2]<=match[i] && begin>end){
					++begin2;
				}
				begin=match[begin2];
				end=match[i];
			}else{
				while(begin2<i && ((match[begin2]<=end && match[begin2]<=match[i])
						 || match[begin2]>end)){
					++begin2;
				}
				begin=match[begin2];
				end=match[i];
			}
		}
		res=max(res,i-begin2+1);
	}

	printf("%d\n",res);

	return 0;
}

#include <cstdio>
#include <algorithm>
using namespace std;

const int MX = 1000006;

int a[MX],as; //substring
int b[MX],bs; //subsequence

int p[MX];
// wyszstko zmodluowac.

long long make_greater(long long x, long long  i, long long what) {
  what-=x;
  int t = ((what/i)+1LL) *i;
  return t+x;
}

int main() {
  scanf("%d%d", &as, &bs);
  for(int i=0; i<as; ++i) scanf("%d", a+i);
  for(int i=0; i<MX; ++i) p[i] = -1;
  for(int i=0; i<bs; ++i) { scanf("%d", b+i); p[b[i]]=i; }
  long long  la=0,ra=0, lb=-1,rb=-1;
  int best = 0;
  while(ra<2*as) {
    if(lb == -1) {
      if(p[a[ra%as]] != -1) { la=ra; lb = p[a[ra%as]]; rb=lb; }
    } else {
      if(p[a[ra%as]] != -1) {
        long long poz = p[a[ra%as]];
        poz = make_greater(poz,bs,rb);
        rb=poz;
        while(rb-lb>=bs || ra-la>=as) {
          ++la;
          poz = p[a[la%as]];
          poz = make_greater(poz,bs,lb);
          lb=poz;
        }
      } else {
        lb = rb = -1;
      }
    }
    if(lb != -1) best = max(best, (int)(ra-la+1LL));
    ++ra;
  }
  printf("%d\n", best);

}

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int Maxn=1010000;

int a[Maxn],b[Maxn];
int pos1[Maxn],pos2[Maxn];
int n,m,res;

bool contain(int x,int l,int r)
{
    if (l==r) return false;
    if (r>l) return x>=l && x<=r;
    else return x>=l || x<=r;
}

int main()
{
    //freopen("x.in","r",stdin);
    //freopen("x.out","w",stdout);

    scanf("%d%d",&n,&m);
    memset(pos1,0,sizeof(pos1));
    memset(pos2,0,sizeof(pos2));
    for (int i=1;i<=n;++i)
    {
        scanf("%d",&a[i]);
        pos1[a[i]]=i;
    }
    for (int i=1;i<=m;++i)
    {
        scanf("%d",&b[i]);
        pos2[b[i]]=i;
    }

    int res=0;
    int len=0;
    for (int i=1,j=i-1;i<=n;++i)
    {
        if (len) --len;
        if (!len) j=i-1;
        for (;;)
        {
            int k=j+1;
            if (k>n) k=1;
            if (k==i && len) break;
            int x=a[k];
            if (pos2[x])
            {
                int y=pos2[x];
                if (!len || !contain(y,pos2[a[i]],pos2[a[j]]))
                    ++len;
            }
            else break;
            j=k;
        }
        res=max(res,len);
    }

    printf("%d\n",res);

    return 0;
}

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <string>
#include <cstring>
using namespace std;

const int maxn = 1111111;
int A[maxn][2];
int B[maxn];
int C[maxn];
int dp[maxn][2];
int pre[maxn][2];
bool vis[maxn][2];

void go(int &i,int &j) {
	j = pre[i][j];
	i --;
}
int calc(int si,int sj,int m) {
	int ei = si , ej = sj;
	int ret = 1;
	int cnt = 1;
	while (pre[ei][ej] != -1) {
		go(ei,ej);
		cnt ++;
		while (A[ei][ej] + m < A[si][sj]) {
			go(si , sj);
			cnt --;
		}
		if (cnt > ret) ret = cnt;
	}
	return ret;
}
int main() {
	int n , m;
	scanf("%d%d",&n,&m);
	for (int i = 0 ; i < n ; i ++) {
		scanf("%d",&A[i][0]);
	}
	memset(C , -1 , sizeof(C));
	for (int i = 0 ; i < m ; i ++) {
		scanf("%d",&B[i]);
		C[ B[i] ] = i;
	}
	for (int i = 0 ; i < n ; i ++) {
		if (C[ A[i][0] ] == -1) {
			A[i][0] = A[i][1] = -1;
		} else {
			A[i][0] = C[ A[i][0] ];
			A[i][1] = A[i][0] + m;
		}
	}
	int ans = 0;
	int N = 2 * n;
	for (int i = 0 ; i < N ; i ++) {
		if (A[i][0] != -1) {
			if (i == 0 || A[i-1][0] == -1) {
				dp[i][0] = dp[i][1] = 1;
				pre[i][0] = pre[i][1] = -1;
			} else {
				if (A[i][0] > A[i-1][0]) {
					dp[i][0] = dp[i-1][0] + 1;
					pre[i][0] = 0;
					dp[i][1] = dp[i-1][1] + 1;
					pre[i][1] = 1;
				} else {
					dp[i][1] = dp[i-1][0] + 1;
					pre[i][1] = 0;
					dp[i][0] = 1;
					pre[i][0] = -1;
				}
			}
		} else {
			dp[i][0] = dp[i][1] = -1;
			pre[i][0] = pre[i][1] = -1;
		}
	}
	for (int i = N - 1 ; i >= 0 ; i --) {
		for (int j = 0 ; j <= 1 ; j ++) {
			if (vis[i][j]) continue;
			else {
				int ret = calc(i , j , m);
				if (ret > ans) ans = ret;
			}
		}
	}
	printf("%d\n",ans);
	return 0;

}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;

#define N 100000
int a[N], b[N], h[N+1];

int main() {
    int n, m, i, j, k;
    cin>>n>>m;
    memset(h, -1, sizeof(h));
    for (i=0; i<n; i++) cin>>a[i];
    for (i=0; i<m; i++) {
        cin>>b[i];
        h[b[i]] = i;
    }
    int l1=0, r1=0, l2=h[a[0]], r2=h[a[0]], res =0;
    k = (l2==-1?0:1);
    while (1) {
        i = (r1+1)%n;
        j = h[a[i]];
        if ((l2<=r2 && (j>r2 || j<l2)) || (l2>r2 && j>r2 && j<l2))
            r2 = j, r1++, k++;
        else {
            res = max(k, res);
            if (i<l1) break;
            l1 = r1 = i, l2=h[a[i]], r2=h[a[i]], k=(l2==-1?0:1);
        }
    }
    cout<<res<<endl;
}