Problem:
Score : 1500 points

Problem Statement

#nck {
width: 30px;
height: auto;
}

Shik's job is very boring. At day 0, his boss gives him a string S_0 of length N which consists of only lowercase English letters. In the i-th day after day 0, Shik's job is to copy the string S_{i-1} to a string S_i. We denote the j-th letter of S_i as S_i[j].

Shik is inexperienced in this job. In each day, when he is copying letters one by one from the first letter to the last letter, he would make mistakes. That is, he sometimes accidentally writes down the same letter that he wrote previously instead of the correct one. More specifically, S_i[j] is equal to either S_{i-1}[j] or S_{i}[j-1]. (Note that S_i[1] always equals to S_{i-1}[1].)

You are given the string S_0 and another string T.
Please determine the smallest integer i such that S_i could be equal to T. If no such i exists, please print -1.

Constraints

1 \leq N \leq 1,000,000

The lengths of S_0 and T are both N.

Both S_0 and T consist of lowercase English letters.

Input

The input is given from Standard Input in the following format:

N
S_0
T

Output

Print the smallest integer i such that S_i could be equal to T. If no such i exists, print -1 instead.

Sample Input 1

5
abcde
aaacc

Sample Output 1

2

S_0 = abcde, S_1 = aaccc and S_2 = aaacc is a possible sequence such that S_2 = T.

Sample Input 2

5
abcde
abcde

Sample Output 2

0

Sample Input 3

4
acaa
aaca

Sample Output 3

2

Sample Input 4

5
abcde
bbbbb

Sample Output 4

-1

Solution in C (GCC 5.4.1) (judge verdict: Accepted)

#if 0
cat <<EOF >mistaken-paste
#endif
// thx Ebi-chan!

#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#define _USE_MATH_DEFINES

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>

#define BIG 2000000007
#define VERYBIG 20000000000000007LL

#define MOD 1000000007
#define FOD  998244353
typedef uint64_t ull;
typedef  int64_t sll;

#define N_MAX 1048576

#ifdef __cplusplus
#include <queue>
#include <stack>
#include <tuple>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <functional>
#include <array>

using std::queue;
using std::priority_queue;
using std::stack;
using std::tuple;
using std::set;
using std::map;
using std::vector;
using std::greater;
using std::pair;
using std::string;
using std::get;

template <typename T, typename U>
pair<T, U> operator+(pair<T, U> l, pair<T, U> r) {
	return pair<T, U>(l.first + r.first, l.second + r.second);
}

#endif

#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950
#endif

typedef struct {
	sll a;
	sll b;
} hwll;

typedef struct {
	sll a;
	sll b;
	sll c;
} hwllc;

typedef struct {
	hwll a;
	hwll b;
} linell;

typedef struct {
	double a;
	double b;
} hwreal;

sll n, m;
sll h, w;
sll k;
sll q;
sll va, vb, vc, vd, ve, vf;
ull ua, ub, uc, ud, ue, uf;
long double vra, vrb, vrc;
double vda, vdb, vdc;
char ch, dh;

ull umin (ull x, ull y) {
	return (x < y) ? x : y;
}

ull umax (ull x, ull y) {
	return (x > y) ? x : y;
}

sll smin (sll x, sll y) {
	return (x < y) ? x : y;
}

sll smax (sll x, sll y) {
	return (x > y) ? x : y;
}

double dmin (double x, double y) {
	return (x < y) ? x : y;
}

double dmax (double x, double y) {
	return (x > y) ? x : y;
}

ull gcd (ull x, ull y) {
	if (y == 0) {
		return x;
	} else {
		return gcd(y, x % y);
	}
}

ull bitpow (ull a, ull x, ull modulo) {
	ull result = 1;
	while (x) {
		if (x & 1) {
			result *= a;
			result %= modulo;
		}
		x /= 2;
		a = (a * a) % modulo;
	}
	return result;
}

ull divide (ull a, ull b, ull modulo) {
	return (a * bitpow(b, modulo - 2, modulo)) % modulo;
}

ull udiff (ull a, ull b) {
	if (a >= b) {
		return a - b;
	} else {
		return b - a;
	}
}

sll sdiff (sll a, sll b) {
	if (a >= b) {
		return a - b;
	} else {
		return b - a;
	}
}

int bitcount (ull n) {
	int result = 0;
	while (n) {
		if (n & 1) result++;
		n /= 2;
	}
	return result;
}

#define BEGCMP(NAME) int32_t NAME (const void *left, const void *right)
#define DEFLR(TYPE) TYPE l=*(TYPE*)left,r=*(TYPE*)right
#define CMPRET(L, R) if((L)<(R))return-1;if((L)>(R))return+1

// int32_t pullcomp (const void *left, const void *right) {
// 	ull l = *(ull*)left;
// 	ull r = *(ull*)right;
// 	if (l < r) {
// 		return -1;
// 	}
// 	if (l > r) {
// 		return +1;
// 	}
// 	return 0;
// }
BEGCMP(pullcomp){
	DEFLR(ull);
	CMPRET(l, r);
	return 0;
}
BEGCMP(prevcomp){
	DEFLR(sll);
	CMPRET(r, l);
	return 0;
}
BEGCMP(psllcomp){
	DEFLR(sll);
	CMPRET(l, r);
	return 0;
}
BEGCMP(pcharcomp){
	DEFLR(char);
	CMPRET(l, r);
	return 0;
}
BEGCMP(pdoublecomp){
	DEFLR(double);
	CMPRET(l, r);
	return 0;
}

int32_t pstrcomp (const void *left, const void *right) {
	char* l = *(char**)left;
	char* r = *(char**)right;

	return strcmp(l, r);
}

BEGCMP(phwllABcomp){
	DEFLR(hwll);
	CMPRET(l.a, r.a);
	CMPRET(l.b, r.b);
	return 0;
}
BEGCMP(phwllREVcomp){
	DEFLR(hwll);
	CMPRET(l.b, r.b);
	CMPRET(l.a, r.a);
	return 0;
}
BEGCMP(ptriplecomp){
	DEFLR(hwllc);
	CMPRET(l.a, r.a);
	CMPRET(l.b, r.b);
	CMPRET(l.c, r.c);
	return 0;
}
BEGCMP(ptripleREVcomp){
	DEFLR(hwllc);
	CMPRET(l.b, r.b);
	CMPRET(l.a, r.a);
	CMPRET(l.c, r.c);
	return 0;
}
BEGCMP(ptripleCABcomp){
	DEFLR(hwllc);
	CMPRET(l.c, r.c);
	CMPRET(l.a, r.a);
	CMPRET(l.b, r.b);
	return 0;
}
BEGCMP(phwrealcomp){
	DEFLR(hwreal);
	CMPRET(l.a, r.a);
	CMPRET(l.b, r.b);
	return 0;
}

int32_t pquadcomp (const void *left, const void *right) {
	linell l = *(linell*)left;
	linell r = *(linell*)right;

	sll ac = phwllABcomp(&(l.a), &(r.a));
	if (ac) return ac;
	sll bc = phwllABcomp(&(l.b), &(r.b));
	if (bc) return bc;

	return 0;
}
int32_t pfracomp (const void *left, const void *right) {
	hwllc l = *(hwllc*)left;
	hwllc r = *(hwllc*)right;

	CMPRET(l.a * r.b, l.b * r.a);
	return 0;
}
bool isinrange (sll left, sll x, sll right) {
	return (left <= x && x <= right);
}

bool isinrange_soft (sll left, sll x, sll right) {
	return (left <= x && x <= right) || (left >= x && x >= right);
}

void sw (sll *l, sll *r) {
	if (*l == *r) return;
	sll t = *l;
	*l = *r;
	*r = t;
}

ull frac[N_MAX * 3], invf[N_MAX * 3];
ull ncr (sll n, sll r, ull m) {
	if (n < 0 || r < 0 || n < r) return 0;
	return frac[n] * (invf[r] * invf[n - r] % m) % m;
}

sll a[N_MAX + 5];
// ull a[N_MAX + 5];
// sll a[3001][3001];
sll b[N_MAX + 5];
// ull b[N_MAX + 5];
// sll b[3001][3001];
sll c[N_MAX + 5];
sll d[N_MAX + 5];
sll e[N_MAX * 4];
char s[N_MAX + 1];
// char s[3010][3010];
char t[N_MAX + 1];
// char t[3010][3010];
char u[N_MAX + 1];
hwll xy[N_MAX + 5];
hwllc tup[N_MAX + 5];
sll table[3005][3005];
ull gin[N_MAX];
// here we go

sll seg[1 << 21], base = 1 << 20;

// void eval (sll i) {
// 	seg[i] += lazy[i];
// 	if (i < base) {
// 		lazy[i * 2] += lazy[i];
// 		lazy[i * 2 + 1] += lazy[i];
// 	}
// 	lazy[i] = 0;
// }
void reset (sll i) {
	if (i < base) {
		// seg[i] = smax(seg[i * 2], seg[i * 2 + 1]);
		seg[i] = seg[i * 2] + seg[i * 2 + 1];
	}
}

// void add_ (sll l, sll r, sll x, sll beg, sll end, sll i) {
// 	eval(i);
// 	if (r <= beg || end <= l) return;
// 	if (l <= beg && end <= r) {
// 		lazy[i] += x;
// 		eval(i);
// 		return;
// 	}

// 	sll med = (beg + end) / 2;
// 	add_(l, r, x, beg, med, i * 2);
// 	add_(l, r, x, med, end, i * 2 + 1);
// 	reset(i);
// }
// void add (sll l, sll r, sll x) {
// 	add_(l, r, x, 0, base, 1);
// }

// sll find_ (sll l, sll r, sll beg, sll end, sll i) {
// 	eval(i);
// 	if (r <= beg || end <= l) return -1;
// 	if (l <= beg && end <= r) {
// 		return seg[i];
// 	}

// 	sll med = (beg + end) / 2;
// 	sll vl = find_(l, r, beg, med, i * 2);
// 	sll vr = find_(l, r, med, end, i * 2 + 1);
// 	reset(i);
// 	return smax(vl, vr);
// }
// sll find (sll l, sll r) {
// 	return find_(l, r, 0, base, 1);
// }

void add (sll v, sll x) {
	v += base;
	while (v) {
		seg[v] += x;
		v /= 2;
	}
}

ull solve () {
	sll i, j, ki, li;
	// ull result = 0;
	sll result = 0;
	double dresult = 0;
	// ull maybe = 0;
	sll maybe = 0;
	// ull sum = 0;
	sll sum = 0;
	sll item;
	sll *dpcell;

	ull len = 0;
	i = n - 1;
	j = n - 1;
	while (i >= 0) {
		char ch = t[i];
		while (j >= 0 && s[j] != ch) j--;
		if (j < 0) goto fail;

		a[len] = j;
		c[len] = i;
		while (i > j) {
			if (t[i - 1] != ch) break;
			i--;
		}
		b[len] = i;

		// printf("%lld: %lld ~ %lld\n", a[len], b[len], c[len]);

		len++;

		i--;
		j--;
	}

	// I can do this in O(N log N) (seg'[i] := seg[i] - seg[i - 1]) but I am lazy

	// seg[i] = a[len - 1 - i]
	// seg[all] = N - 1
	// add(len, base, n - 1);
	sll prev = 0;
	for (i = 0; i < len; i++) {
		ull v = len - 1 - i;
		
		seg[base + i] = a[v] - prev;
		prev = a[v];
	}
	seg[base + len] = (n - 1) - prev;

	for (i = base - 1; i; i--) reset(i);

	for (i = len - 1; i >= 0; i--) {
		ull v = len - 1 - i;

		// seg[i] = a[v]
		// add(i, i + 1, a[v]);

		// min{x | seg[x]>=c[v]} (binary search)
		// cmax(result, x - i)
		// sll ok = base - 1, ng = i - 1;
		// while (ng + 1 < ok) {
		// 	sll med = (ok + ng) / 2;
		// 	if (find(i, med + 1) >= c[v]) {
		// 		ok = med;
		// 	} else {
		// 		ng = med;
		// 	}
		// }
		sll ok = 1;
		sll left = 0;
		while (ok < base) {
			if (left + seg[ok * 2] >= c[v]) {
				ok = ok * 2;
			} else {
				left += seg[ok * 2];
				ok = ok * 2 + 1;
			}
		}
		ok -= base;
		result = smax(result, ok - i);

		// seg[x] = c[v]
		// seg[i~]--
		// add(ok, ok + 1, c[v] - find(ok, ok + 1));
		add(ok, c[v] - seg[base + ok]);
		// add(i, base, -1);
		add(i, -1);
	}

	printf("%lld\n", result);
	// printf("%.15f\n", dresult);
	// puts(s);

	return 0;

	success:
	// puts("YES");
	puts("Yes");
	// printf("%llu\n", result);
	// puts("0");
	// puts("First");
	return 0;

	fail:
	// puts("NO");
	// puts("No");
	// puts("0");
	puts("-1");
	// puts("-1 -1 -1");
	// puts("Second");
	return 1;
}

int32_t main (int argc, char *argv[]) {
	int32_t i, j;

	n = 4;
	m = 0;

	// scanf("%llu", &m);
	// scanf("%llu%llu", &h, &w);
	scanf("%llu", &n, &m);
	// scanf("%llu", &k, &n, &m);
	// scanf("%llu%llu", &h, &w);
	// scanf("%llu", &q);
	// scanf("%lld%lld", &va, &vb, &vc, &vd);
	// va--;
	// vb--;
	// scanf("%llu%llu%llu%llu", &ua, &ub, &uc, &ud, &ue);
	scanf("%s", s);
	scanf("%s", t);
	// scanf("%s", u);
	// scanf("%llu", &k);
	// scanf("%lld", &m);
	// for (i = 0; i < n; i++) {
	// 	// scanf("%lld", &a[i]);
	// 	scanf("%lld", &d[i]);
	// }
	// scanf("%llu", &q);
	for (i = 0; i < 0; i++) {
		// scanf("%lld%lld", &xy[i].a, &xy[i].b);
		// scanf("%lld%lld%lld", &tup[i].a, &tup[i].b, &tup[i].c);
		// scanf("%lld", &c[i]);

		scanf("%lld", &a[i]);
		// scanf("%lld", &b[i]);
		// scanf("%lld", &c[i]);
		// scanf("%lld", &d[i]);
		// a[i]--;
		// b[i]--;
		// c[i]--;
		// d[i]--;
		// xy[i].a--;
		// xy[i].b--;
		// tup[i].a--;
		// tup[i].b--;
	}
	// scanf("%llu", &m);
	// scanf("%llu", &q);
	// for (i = 0; i < m; i++) {
	// 	scanf("%lld%lld", &xy[i].a, &xy[i].b);
	// 	xy[i].a--;
	// 	xy[i].b--;
	// 	// scanf("%lld%lld", &a[i], &b[i]);
	// 	// scanf("%lld", &b[i]);
	// 	// a[i]--;
	// 	// b[i]--;
	// 	// scanf("%lld", &c[i]);
	// 	// scanf("%lld", &d[i]);
	// 	// scanf("%lld", &e[i]);
	// 	// c[i]--;
	// 	// d[i]--;
	// }

	// for (i = 0; i < q; i++) {
	// 	// scanf("%lld%lld", &xy[i].a, &xy[i].b);
	// 	scanf("%lld", &c[i]);
	// 	// xy[i].a--;
	// 	// xy[i].b--;
	// }

	// for (i = 0; i < h; i++) {
	// 	for (j = 0; j < w; j++) {
	// 		scanf("%lld", &table[i][j]);
	// 		// table[i][j]--;
	// 	}
	// }
	// for (i = 0; i < h; i++) {
	// 	scanf("%s", s[i]);
	// }
	// scanf("%llu", &q);

	solve();

	return 0;
}