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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using Debug = System.Diagnostics.Debug;
using SB = System.Text.StringBuilder;
//using System.Numerics;
using static System.Math;
using Number = System.Int32;
namespace Program {
    public class Solver {
        Random rnd = new Random();
        public void Solve() {
            var n = ri + 1;
            var s = "$" + rs;
            var t = "$" + rs;
            var l = -1; var r = n;
            var b = f(t);
            var a = new List<int>();
            for (int i = b.Count - 1, j = s.Length - 1; i >= 0; i--)
            {
                while (j > 0 && (s[j] != t[b[i]] || j > b[i])) j--;
                a.Add(j);
            }
            a.Reverse();
            if (a[0] == 0) { Console.WriteLine(-1); return; }
            else if (s == t) { Console.WriteLine(0); return; }
            Debug.WriteLine(a.AsJoinedString());
            Debug.WriteLine(b.AsJoinedString());
            while (r - l > 1)
            {
                var x = (l + r) / 2;
                if (func(x, a, b)) r = x;
                else l = x;
            }
            Console.WriteLine(r + 1);
        }

        bool func(int x, List<int> a, List<int> b) {
            for (int i = a.Count - 1; i >= 0; i--)
                if (i + x < b.Count && a[i + x] - x < b[i]) return false;
            return true;
        }

        List<int> f(string s) {
            var ret = new List<int>();
            for (int i = s.Length - 1; i > 0; i--)
                if (s[i] != s[i - 1]) ret.Add(i);
            ret.Reverse();
            return ret;
        }
        const long INF = 5L << 60;
        static int[] dx = { -1, 0, 1, 0 };
        static int[] dy = { 0, 1, 0, -1 };
        int ri { get { return sc.Integer(); } }
        long rl { get { return sc.Long(); } }
        double rd { get { return sc.Double(); } }
        string rs { get { return sc.Scan(); } }
        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

        static T[] Enumerate<T>(int n, Func<int, T> f) {
            var a = new T[n];
            for (int i = 0; i < n; ++i) a[i] = f(i);
            return a;
        }
        static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
    }
}

#region main
static class Ex {
    static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
        return string.Join(st, ie);
    }
    static public void Main() {
        Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Program.Solver();
        try
        {
            solver.Solve();
            Console.Out.Flush();
        }
        catch { }
    }
}
#endregion
#region Ex
namespace Program.IO {
    using System.IO;
    using System.Text;
    using System.Globalization;

    public class Printer: StreamWriter {
        public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
        public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
    }

    public class StreamScanner {
        public StreamScanner(Stream stream) { str = stream; }

        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;
        public bool IsEndOfStream { get { return isEof; } }

        private byte read() {
            if (isEof) return 0;
            if (ptr >= len)
            {
                ptr = 0;
                if ((len = str.Read(buf, 0, 1024)) <= 0)
                {
                    isEof = true;
                    return 0;
                }
            }
            return buf[ptr++];
        }

        public char Char() {
            byte b = 0;
            do b = read(); while ((b < 33 || 126 < b) && !isEof);
            return (char)b;
        }
        public string Scan() {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
            return sb.ToString();
        }
        public string ScanLine() {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
            return sb.ToString();
        }
        public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
        public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
        public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
    }
}

#endregion