Problem:
Score : 500 points

Problem Statement

Given are two strings s and t consisting of lowercase English letters. Determine if there exists an integer i satisfying the following condition, and find the minimum such i if it exists.

Let s' be the concatenation of 10^{100} copies of s. t is a subsequence of the string {s'}_1{s'}_2\ldots{s'}_i (the first i characters in s').

Notes

A subsequence of a string a is a string obtained by deleting zero or more characters from a and concatenating the remaining characters without changing the relative order. For example, the subsequences of contest include net, c, and contest.

Constraints

1 \leq |s| \leq 10^5

1 \leq |t| \leq 10^5

s and t consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s
t

Output

If there exists an integer i satisfying the following condition, print the minimum such i; otherwise, print -1.

Sample Input 1

contest
son

Sample Output 1

10

t = son is a subsequence of the string contestcon (the first 10 characters in s' = contestcontestcontest...), so i = 10 satisfies the condition.

On the other hand, t is not a subsequence of the string contestco (the first 9 characters in s'), so i = 9 does not satisfy the condition.

Similarly, any integer less than 9 does not satisfy the condition, either. Thus, the minimum integer i satisfying the condition is 10.

Sample Input 2

contest
programming

Sample Output 2

-1

t = programming is not a substring of s' = contestcontestcontest.... Thus, there is no integer i satisfying the condition.

Sample Input 3

contest
sentence

Sample Output 3

33

Note that the answer may not fit into a 32-bit integer type, though we cannot put such a case here.

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using static Library.Comfort;
using static Library.Math;
using static Library.Algorithm;
using static System.Math;
using System.ComponentModel;

namespace AtCoderer
{
    public class App
    {
        public static void Solve()
        {
            string s, t;

            s = Console.ReadLine();
            t = Console.ReadLine();
            var cst = new List<int>[26];
            for (int i = 0; i < cst.Length; i++)
            {
                cst[i] = new List<int>();
            }
            for (int i = 0; i < s.Length; i++)
            {
                cst[s[i] - 'a'].Add(i);
            }
            var cs = new int[26][];
            for(int i = 0;i<26;i++)
            {
                cs[i] = cst[i].ToArray();
            }
            int current = -1;
            int sum = 0;
            foreach (var c in t)
            {
                var i = ~Array.BinarySearch(cs[c - 'a'],current);
                if (i == cs[c - 'a'].Length)
                    i = 0;
                if(cs[c - 'a'].Length == 0)
                {
                    cout = -1;
                    return;
                }
                if(current < cs[c - 'a'][i])
                {
                    current = cs[c - 'a'][i];
                }
                else
                {
                    sum++;
                    current = cs[c - 'a'][i];
                }
            }
            cout = sum * s.Length + current + 1;
        }
        public static void Main(string[] args)
        {
#if DEBUG
            while (true)
            {
                Solve();
            }
#else
            Solve();
#endif
        }
    }
}
namespace Library
{
    public static class Comfort
    {
        public const int mod = 1000000007;
        public class Point
        {
            public int a;
            public int b;
            public Point(int a, int b)
            {
                this.a = a;
                this.b = b;
            }
        }
        public static void DWrite<T>(T o)
        {
#if DEBUG
            Console.WriteLine(o);
#endif
        }
        public static int[] OrderBy(this int[] IArr)
        {
            int[] arr = new int[IArr.Length];
            Array.Copy(IArr, arr, IArr.Length);
            Array.Sort(arr);
            return arr;
        }
        public static int Max(params int[] p) => p.Max();
        public static long Max(params long[] p) => p.Max();
        public static int Min(params int[] p) => p.Min();
        public static long Min(params long[] p) => p.Min();
        public static int In()
        {
            return int.Parse(Console.ReadLine());
        }
        public static int Inl()
        {
            return int.Parse(Console.ReadLine());
        }
        public static int[] Parse()
        {
            return Console.ReadLine().Split().Select(v => int.Parse(v)).ToArray();
        }
        public static long[] Parsel()
        {
            return Console.ReadLine().Split().Select(v => long.Parse(v)).ToArray();
        }
        public static void Parse(out int a, out int b)
        {
            var r = Console.ReadLine().Split().Select(v => int.Parse(v)).ToArray();
            a = r[0];
            b = r[1];
        }
        public static void Parse(out int a, out int b, out int c)
        {
            var r = Console.ReadLine().Split().Select(v => int.Parse(v)).ToArray();
            a = r[0];
            b = r[1];
            c = r[2];
        }
        public static void Parse(out int a, out int b, out int c, out int d)
        {
            var r = Console.ReadLine().Split().Select(v => int.Parse(v)).ToArray();
            a = r[0];
            b = r[1];
            c = r[2];
            d = r[3];
        }
        public static void Parse(out long a, out long b)
        {
            var r = Console.ReadLine().Split().Select(v => long.Parse(v)).ToArray();
            a = r[0];
            b = r[1];
        }
        public static void Parse(out long a, out long b, out long c)
        {
            var r = Console.ReadLine().Split().Select(v => long.Parse(v)).ToArray();
            a = r[0];
            b = r[1];
            c = r[2];
        }
        public static void Parse(out long a, out long b, out long c, out long d)
        {
            var r = Console.ReadLine().Split().Select(v => long.Parse(v)).ToArray();
            a = r[0];
            b = r[1];
            c = r[2];
            d = r[3];
        }
        public static string ToString(this IEnumerable<char> v)
        {
            return string.Join("", v);
        }
        public static string Join<T>(this IEnumerable<T> v)
        {
            return string.Join(" ", v);
        }
        public static string Join<T>(this IEnumerable<T> v, char c)
        {
            return string.Join(c.ToString(), v);
        }
        public static string Join<T>(this IEnumerable<T> v, string s)
        {
            return string.Join(s, v);
        }
        public static object cout
        {
            set
            {
                Console.WriteLine(value);
            }
        }
        public static object dout
        {
            set
            {
                DWrite(value);
            }
        }
    }
    public static class Math
    {
        public static bool IsNatural(this float v) => v - (int)v == 0;
        public static bool IsNatural(this double v) => v - (int)v == 0;
        public static long nCm(long n, long m)
        {
            if (m == 0) return 1;
            if (n == 0) return 0;
            return n * nCm(n - 1, m - 1) / m;
        }
        public static IEnumerable<int> Factor(int n)
        {
            int i = 2;
            int tmp = n;

            while (i * i <= n)
            {
                if (tmp % i == 0)
                {
                    tmp /= i;
                    yield return i;
                }
                else
                {
                    i++;
                }
            }
            if (tmp != 1) yield return tmp;
        }
        public static int Gcd(int a, int b) => a > b ? GcdRecursive(a, b) : GcdRecursive(b, a);
        private static int GcdRecursive(int x, int y) => y == 0 ? x : GcdRecursive(y, x % y);
        public static long Gcd(long a, long b) => a > b ? GcdRecursive(a, b) : GcdRecursive(b, a);
        private static long GcdRecursive(long x, long y) => y == 0 ? x : GcdRecursive(y, x % y);
        public static long Lcm(int a, int b) => ((long)a) * b / Gcd(a, b);
    }
    public static class Algorithm
    {
        public static IEnumerable<KeyValuePair<T,int>> UniteNext<T>(this IEnumerable<T> arr) where T:IEquatable<T>
        {
            int cont = 0;
            T prev = arr.First();
            foreach(var v in arr)
            {
                if(v.Equals(prev))
                {
                    cont++;
                }
                else
                {
                    yield return new KeyValuePair<T, int>(prev, cont);
                    cont = 1;
                }
                prev = v;
            }
            yield return new KeyValuePair<T, int>(prev, cont);
        }
        public class EnumAll
        {
            bool Over = false;
            int UpperValue;
            int Dimension;
            public int[] Current { private set; get; }
            public EnumAll(int MaxValue, int Dimension)
            {
                this.Dimension = Dimension;
                UpperValue = MaxValue;
                Current = new int[Dimension];
                Current[0] = -1;
            }
            public bool Next()
            {
                if (Over)
                    return false;
                bool flag = false;
                for (int i = 0; i < Dimension; i++)
                {
                    if (++Current[i] >= UpperValue)
                        Current[i] = 0;
                    else
                    {
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    Over = true;
                    return false;
                }
                return true;
            }
        }
        public class Graph
        {
            public int Count = -1;
            private HashSet<int>[] Joined;
            public static Graph GenerateComplete(int size)
            {
                throw new NotImplementedException();
            }
            public Graph(int size)
            {
                Joined = new HashSet<int>[size];
                for (int i = 0; i < Joined.Length; i++)
                    Joined[i] = new HashSet<int>();
                Count = size;
            }
            public int[] GetConnected(int index)
            {
                return Joined[index].ToArray();
            }
            public void AddEdge(int a, int b)
            {
                if (a == b)
                    DWrite("ループを追加することはできません A:" + a + " B:" + b);
                else
                {
                    if (!Joined[a].Add(b))
                        DWrite("多重辺を追加することはできません A:" + a + " B:" + b);
                    else
                        Joined[b].Add(a);
                }
            }
            public int[] ToTree(int Root)
            {
                var ar = new int[Count];
                for (int i = 0; i < ar.Length; i++)
                    ar[i] = -10000000;
                ar[Root] = -1;
                Queue<int> bfs = new Queue<int>();
                bfs.Enqueue(Root);
                while (bfs.Count != 0)
                {
                    var t = bfs.Dequeue();
                    foreach (var v in Joined[t])
                    {
                        bfs.Enqueue(v);
                        if (ar[v] == -10000000)
                            ar[v] = t;
                    }
                }
                return ar;
            }
        }
        public class UnionFind
        {
            private int[] Parent;
            private int GetRoot(int v)
            {
                if (Parent[v] < 0)
                    return v;
                else
                    return Parent[v] = GetRoot(Parent[v]);
            }
            public UnionFind(int size)
            {
                Parent = new int[size];
                for (int i = 0; i < size; i++)
                    Parent[i] = -1;
            }
            public bool AreGrouped(int a, int b)
            {
                return GetRoot(a) == GetRoot(b);
            }
            public void Connect(int a, int b)
            {
                a = GetRoot(a);
                b = GetRoot(b);
                if (a == b) return;
                if (Parent[b] < Parent[a])
                {
                    Parent[b] += Parent[a];
                    Parent[a] = b;
                }
                else
                {
                    Parent[a] += Parent[b];
                    Parent[b] = a;
                }
            }
            public int GetGroupSize(int a)
            {
                return -Parent[GetRoot(a)];
            }
        }
        public class PriorityQueue<T> where T : IComparable
        {
            List<T> buffer = new List<T>();
            static void PushHeap(List<T> array, T elem)
            {
                int n = array.Count;
                array.Add(elem);

                while (n != 0)
                {
                    int i = (n - 1) / 2;
                    if (array[n].CompareTo(array[i]) < 0)
                    {
                        T tmp = array[n]; array[n] = array[i]; array[i] = tmp;
                    }
                    n = i;
                }
            }
            static void PopHeap(List<T> array)
            {
                int n = array.Count - 1;
                array[0] = array[n];
                array.RemoveAt(array.Count - 1);

                for (int i = 0, j; (j = 2 * i + 1) < n;)
                {
                    if ((j != n - 1) && (array[j].CompareTo(array[j + 1]) > 0))
                        j++;
                    if (array[i].CompareTo(array[j]) > 0)
                    {
                        T tmp = array[j]; array[j] = array[i]; array[i] = tmp;
                    }
                    i = j;
                }
            }
            public int Count
            {
                get
                {
                    return buffer.Count;
                }
            }
            public void Push(T elem)
            {
                PushHeap(this.buffer, elem);
            }
            public T Peek()
            {
                return buffer[0];
            }

            public T Pop()
            {
                T a = buffer[0];
                PopHeap(this.buffer);
                return a;
            }
        }
        public class KMP
        {
            int[] Table;
            string a,b;
            int m = 0;
            int i = 0;
            public KMP(string a)
            {
                this.a = a;
                Table = new int[a.Length];
                int subindex = 0;

                Table[0] = -1;
                Table[1] = 0;

                for (int i = 2; i < a.Length;)
                {
                    if (a[i - 1] == a[subindex])
                    {
                        subindex++;
                        Table[i] = subindex;
                        i++;
                    }
                    else if (subindex > 0)
                        subindex = Table[subindex];
                    else
                    {
                        Table[i] = 0;
                        i++;
                    }
                }
            }
            public void SetSearchBase(string v)
            {
                b = v;
                m = 0;
                i = 0;
            }
            public int Search()
            {
                m++;
                i = 0;
                while (m + i < b.Length)
                {
                    if (a[i] == b[m + i])
                    {
                        i++;
                        if (i == a.Length)
                            return m;
                    }
                    else
                    {
                        m = m + i - Table[i];
                        if (i > 0)
                            i = Table[i];
                    }
                }
                return -1;
            }
        }
    }
}