Problem:
Score : 200 points

Problem Statement

Niwango created a playlist of N songs.
The title and the duration of the i-th song are s_i and t_i seconds, respectively.
It is guaranteed that s_1,\ldots,s_N are all distinct.

Niwango was doing some work while playing this playlist. (That is, all the songs were played once, in the order they appear in the playlist, without any pause in between.)
However, he fell asleep during his work, and he woke up after all the songs were played.
According to his record, it turned out that he fell asleep at the very end of the song titled X.

Find the duration of time when some song was played while Niwango was asleep.

Constraints

1 \leq N \leq 50

s_i and X are strings of length between 1 and 100 (inclusive) consisting of lowercase English letters.

s_1,\ldots,s_N are distinct.

There exists an integer i such that s_i = X.

1 \leq t_i \leq 1000

t_i is an integer.

Input

Input is given from Standard Input in the following format:

N
s_1 t_1
\vdots
s_{N} t_N
X

Output

Print the answer.

Sample Input 1

3
dwango 2
sixth 5
prelims 25
dwango

Sample Output 1

30

While Niwango was asleep, two songs were played: sixth and prelims.

The answer is the total duration of these songs, 30.

Sample Input 2

1
abcde 1000
abcde

Sample Output 2

0

No songs were played while Niwango was asleep.

In such a case, the total duration of songs is 0.

Sample Input 3

15
ypnxn 279
kgjgwx 464
qquhuwq 327
rxing 549
pmuduhznoaqu 832
dagktgdarveusju 595
wunfagppcoi 200
dhavrncwfw 720
jpcmigg 658
wrczqxycivdqn 639
mcmkkbnjfeod 992
htqvkgkbhtytsz 130
twflegsjz 467
dswxxrxuzzfhkp 989
szfwtzfpnscgue 958
pmuduhznoaqu

Sample Output 3

6348

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

public class ABC
{
    //          long[] sp = Console.ReadLine().Split().Select(long .Parse).ToArray();
    //          int[] sp = Console.ReadLine().Split().Select(int.Parse).ToArray();
    //          int N =  int.Parse(Console.ReadLine());
    //CompLib.Collections.PriorityQueue<?>

    public static void Main()
    {
        int N = int.Parse(Console.ReadLine());
        Tuple<string, long>[] tuple = new Tuple<string, long>[N];
        long sum = 0;
        for (int i = 0; i < N; i++)
        {
            string st = Console.ReadLine();
            string[] split = st.Split();
            long time = long.Parse(split[1]);
            tuple[i] = new Tuple<string, long>(split[0], time);

            sum += time;

        }
        string X = Console.ReadLine();

        for (int i = 0; i < N; i++)
        {
            sum -= tuple[i].Item2;
            if (tuple[i].Item1 == X)
            {

                break;
            }
        }


        Console.WriteLine(sum);
    }


}



class readint
{



    public readint(out int i)
    {
        i = int.Parse(Console.ReadLine());

    }
    public readint(out int a, out int b)
    {
        int[] sp = Console.ReadLine().Split().Select(int.Parse).ToArray();
        a = sp[0];
        b = sp[1];

    }
    public readint(out int a, out int b, out int c)
    {
        int[] sp = Console.ReadLine().Split().Select(int.Parse).ToArray();
        a = sp[0];
        b = sp[1];
        c = sp[2];
    }
    public readint(out int a, out int b, out int c, out int d)
    {
        int[] sp = Console.ReadLine().Split().Select(int.Parse).ToArray();
        a = sp[0];
        b = sp[1];
        c = sp[2];
        d = sp[3];

    }

}

class readlong
{


    public readlong(out long i)
    {
        i = long.Parse(Console.ReadLine());

    }
    public readlong(out long a, out long b)
    {
        long[] sp = Console.ReadLine().Split().Select(long.Parse).ToArray();
        a = sp[0];
        b = sp[1];

    }
    public readlong(out long a, out long b, out long c)
    {
        long[] sp = Console.ReadLine().Split().Select(long.Parse).ToArray();
        a = sp[0];
        b = sp[1];
        c = sp[2];
    }
    public readlong(out long a, out long b, out long c, out long d)
    {
        long[] sp = Console.ReadLine().Split().Select(long.Parse).ToArray();
        a = sp[0];
        b = sp[1];
        c = sp[2];
        d = sp[3];

    }

}







class Util
{




    /// <summary>
    /// 2引数の最大公約数を返します。longです。
    /// </summary>
    /// <param name="a">long 引数1</param>
    /// <param name="b">long 引数2</param>
    /// <returns></returns>
    public static long GCD(long a, long b)
    {
        if (a < b)
            swap(ref a, ref b);
        if (a % b == 0) return b;
        return GCD(b, a % b);

    }
    /// <summary>
    /// 2引数の最大公約数を返します。intです。
    /// </summary>
    /// <param name="a">int 引数1</param>
    /// <param name="b">int 引数2</param>
    /// <returns></returns>
    public static int GCD(int a, int b)
    {
        if (a < b)
            swap(ref a, ref b);
        if (a % b == 0) return b;
        return GCD(b, a % b);
    }

    /// <summary>
    /// 2つの変数の中身を交換する。型はなんでもいい
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="a"></param>
    /// <param name="b"></param>
    public static void swap<T>(ref T a, ref T b)
    {
        T temp = b;
        b = a;
        a = temp;

    }

    /// <summary>
    /// 2引数の最大公約数を返します。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static long LCM(long a, long b)
    {
        return a * b / GCD(a, b);
    }
    /// <summary>
    /// 2引数の最大公約数を返します。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static long LCM(int a, int b)
    {
        return Math.BigMul(a, b) / GCD(a, b);
    }


    public static int M = (int)(Math.Pow(10, 9)) + 7;
    private static int[] factorial_modM;

    /// <summary>
    /// 2引数の積 mod Mを求める。Mは10億7。
    /// 変えられるよ。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static int Multiple_modM(int a, int b)
    {
        return (int)(Math.BigMul(a, b) % M);
    }
    /// <summary>
    /// n! modMを求めるための準備を行う。引数は最大値。
    /// </summary>
    /// <param name="n"></param>
    public static void factorial_modM_Prepare(int n)
    {
        factorial_modM = new int[n + 1];
        factorial_modM[0] = 1;
        for (int i = 1; i <= n; ++i)
        {
            factorial_modM[i] = Multiple_modM(factorial_modM[i - 1], i);
        }
    }

    /// <summary>
    /// n! mod M を返す。やる前にfactorial_modM_Prepare(n)を実行しといてね。
    /// </summary>
    /// <param name="n"></param>
    /// <returns></returns>
    public static int Factorial(int n)
    {
        return factorial_modM[n];
    }


    public static int Pow(int a, int m)
    {
        switch (m)
        {
            case 0:
                return 1;
            case 1:
                return a;
            default:
                int p1 = Pow(a, m / 2);
                int p2 = Multiple_modM(p1, p1);
                return ((m % 2) == 0) ? p2 : Multiple_modM(p2, a);
        }
    }
    /// <summary>
    /// a / m Mod M を求める。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static int Div(int a, int b)
    {
        return Multiple_modM(a, Pow(b, M - 2));
    }
    /// <summary>
    /// nCr mod M を求める。やる前にfactorial_modM_Prepare(n)を実行しといてね。
    /// </summary>
    /// <param name="n"></param>
    /// <param name="r"></param>
    /// <returns></returns>
    public static int nCr_modM(int n, int r)
    {
        if (r < 0) return 0;

        if (n < r) { return 0; }
        if (n == r) { return 1; }
        int res = Factorial(n);
        res = Div(res, Factorial(r));
        res = Div(res, Factorial(n - r));
        return res;
    }

}
/// <summary>
/// Union-Find木を定義する。コンストラクタの指定は、頂点の番号。
/// おすすめとしては、UnionFind<T>[] で宣言してしまう。
/// </summary>
/// <typeparam name="T">int固定でいいよね。</typeparam>
class UnionFind<T>
{
    public int tree_height;
    public UnionFind<T> parent;
    public T item
    {
        get;
        private set;
    }

    public UnionFind(T item)
    {
        tree_height = 0;
        parent = this;

    }

    /// <summary>
    /// 一番上の親を探す。
    /// 探しながら繋がり方を最適化している。
    /// UnionFindの頂点そのものを返すので、==での比較が可能。
    /// </summary>
    /// <returns></returns>
    public UnionFind<T> FindAdam()
    {
        if (parent == this) return this;
        else
        {
            UnionFind<T> ParentOfParent = parent.FindAdam();
            parent = ParentOfParent;//縦長な構成をつなぎ直している
            return ParentOfParent;
        }
    }
    /// <summary>
    /// unionfind2つを一つにつなぐ。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    public static void Unite(UnionFind<T> a, UnionFind<T> b)
    {
        UnionFind<T> ParentOfA = a.FindAdam();
        UnionFind<T> ParentOfB = b.FindAdam();
        if (ParentOfA.tree_height < ParentOfB.tree_height)
        {
            ParentOfA.parent = ParentOfB;
            ParentOfB.tree_height = Math.Max(ParentOfA.tree_height + 1, ParentOfB.tree_height);
        }
        else
        {
            ParentOfB.parent = ParentOfA;
            ParentOfA.tree_height = Math.Max(ParentOfB.tree_height + 1, ParentOfA.tree_height);
        }

    }

}

//Treap 平衡二分木
class Treap<T> where T : IComparable
{
    private class Node
    {
        private static Random g_rand = new Random();
        private readonly int m_rank = g_rand.Next();
        private readonly T m_value;
        private Node m_lch;
        private Node m_rch;
        private int m_count;

        public Node(T value)
        {
            m_value = value;
            m_count = 1;
        }

        private static int Count(Node node)
        {
            return (node != null) ? node.m_count : 0;
        }

        private Node Update()
        {
            m_count = Count(m_lch) + Count(m_rch) + 1;
            return this;
        }

        public static Node Merge(Node a, Node b)
        {
            if (a == null) { return b; }
            if (b == null) { return a; }

            if (a.m_rank < b.m_rank)
            {
                a.m_rch = Merge(a.m_rch, b);
                return a.Update();
            }
            else
            {
                b.m_lch = Merge(a, b.m_lch);
                return b.Update();
            }
        }

        public static Tuple<Node, Node> Split(Node t, int k)
        {
            if (t == null) { return new Tuple<Node, Node>(null, null); }

            if (k <= Count(t.m_lch))
            {
                var pair = Split(t.m_lch, k);
                t.m_lch = pair.Item2;
                return new Tuple<Node, Node>(pair.Item1, t.Update());
            }
            else
            {
                var pair = Split(t.m_rch, k - Count(t.m_lch) - 1);
                t.m_rch = pair.Item1;
                return new Tuple<Node, Node>(t.Update(), pair.Item2);
            }
        }

        public int FindIndex(T value)
        {
            int L = Count(m_lch);
            if (value.CompareTo(m_value) < 0)
            {
                return (m_lch != null) ? m_lch.FindIndex(value) : 0;
            }
            else if (value.CompareTo(m_value) > 0)
            {
                return (m_rch != null) ? m_rch.FindIndex(value) + L + 1 : L + 1;
            }
            else
            {
                return L;
            }
        }

        public T this[int i]
        {
            get
            {
                int L = Count(m_lch);
                if (i < L)
                {
                    return m_lch[i];
                }
                else if (i > L)
                {
                    return m_rch[i - L - 1];
                }
                else
                {
                    return m_value;
                }
            }
        }
    }

    private Node node;

    public void Insert(T value)
    {
        if (node != null)
        {
            int k = node.FindIndex(value);
            var pair = Node.Split(node, k);
            node = Node.Merge(Node.Merge(pair.Item1, new Node(value)), pair.Item2);
        }
        else
        {
            node = new Node(value);
        }
    }

    public int FindIndex(T value)
    {
        return node.FindIndex(value);
    }

    public T this[int i]
    {
        get
        {
            return node[i];
        }
    }
}

static class Permutation<T>
{
    private static void Search(List<T[]> perms, Stack<T> stack, T[] a)
    {
        int N = a.Length;
        if (N == 0)
        {
            perms.Add(stack.Reverse().ToArray());
        }
        else
        {
            var b = new T[N - 1];
            Array.Copy(a, 1, b, 0, N - 1);
            for (int i = 0; i < a.Length; ++i)
            {
                stack.Push(a[i]);
                Search(perms, stack, b);
                if (i < b.Length) { b[i] = a[i]; }
                stack.Pop();
            }
        }
    }
    public static IEnumerable<T[]> All(IEnumerable<T> src)
    {
        var perms = new List<T[]>();
        Search(perms, new Stack<T>(), src.ToArray());
        return perms;
    }
}



namespace CompLib.Collections
{
    #region PriorityQueue
    /// <summary>
    /// 指定した型のインスタンスを最も価値が低い順に取り出すことが可能な可変サイズのコレクションを表します．
    /// </summary>
    /// <typeparam name="T">優先度付きキュー内の要素の型を指定します．</typeparam>
    /// <remarks>内部的にはバイナリヒープによって実装されています．</remarks>
    public class PriorityQueue<T>
    {
        readonly List<T> heap = new List<T>();
        readonly Comparison<T> cmp;

        /// <summary>
        /// デフォルトの比較子を使用してインスタンスを初期化します．
        /// </summary>
        /// <remarks>この操作は O(1) で実行されます．</remarks>
        public PriorityQueue() { cmp = Comparer<T>.Default.Compare; }

        /// <summary>
        /// デリゲートで表されるような比較関数を使用してインスタンスを初期化します．
        /// </summary>
        /// <param name="comparison"></param>
        /// <remarks>この操作は O(1) で実行されます．</remarks>
        public PriorityQueue(Comparison<T> comparison) { cmp = comparison; }

        /// <summary>
        /// 指定された比較子を使用してインスタンスを初期化します．
        /// </summary>
        /// <param name="comparer"></param>
        /// <remarks>この操作は O(1) で実行されます．</remarks>
        public PriorityQueue(IComparer<T> comparer) { cmp = comparer.Compare; }

        /// <summary>
        /// 優先度付きキューに要素を追加します．
        /// </summary>
        /// <param name="item">優先度付きキューに追加される要素</param>
        /// <remarks>最悪計算量 O(log N) で実行されます．</remarks>
        public void Enqueue(T item)
        {
            var pos = heap.Count;
            heap.Add(item);
            while (pos > 0)
            {
                var par = (pos - 1) / 2;
                if (cmp(heap[par], item) <= 0)
                    break;
                heap[pos] = heap[par];
                pos = par;
            }
            heap[pos] = item;

        }

        /// <summary>
        /// 優先度付きキューから最も価値が低い要素を削除し，返します．
        /// </summary>
        /// <returns>優先度付きキューから削除された要素．</returns>
        /// <remarks>最悪計算量 O(log N) で実行されます．</remarks>
        public T Dequeue()
        {
            var ret = heap[0];
            var pos = 0;
            var x = heap[heap.Count - 1];

            while (pos * 2 + 1 < heap.Count - 1)
            {
                var lch = pos * 2 + 1;
                var rch = pos * 2 + 2;
                if (rch < heap.Count - 1 && cmp(heap[rch], heap[lch]) < 0) lch = rch;
                if (cmp(heap[lch], x) >= 0)
                    break;
                heap[pos] = heap[lch];
                pos = lch;
            }
            heap[pos] = x;
            heap.RemoveAt(heap.Count - 1);
            return ret;

        }
        /// <summary>
        ///  優先度付きキューに含まれる最も価値が低い要素を削除せずに返します．
        /// </summary>
        /// <returns>優先度付きキューに含まれる最も価値が低い要素．</returns>
        /// <remarks>この操作は O(1) で実行されます．</remarks>
        public T Peek() { return heap[0]; }

        /// <summary>
        /// 優先度付きキュー内の要素の数を取得します．
        /// </summary>
        /// <returns>優先度付キュー内にある要素の数</returns>
        /// <remarks>最悪計算量 O(1) で実行されます．</remarks>
        public int Count { get { return heap.Count; } }
        /// <summary>
        /// 優先度付きキュー内に要素が存在するかどうかを O(1) で判定します．
        /// </summary>
        /// <returns>優先度付キュー内にある要素が存在するならば true，そうでなければ　false．</returns>
        /// <remarks>この操作は O(1) で実行されます．</remarks>
        public bool Any() { return heap.Count > 0; }

        /// <summary>
        /// 優先度付きキューに含まれる要素を昇順に並べて返します．
        /// </summary>
        /// <remarks>この操作は計算量 O(N log N)で実行されます．</remarks>
        public T[] Items
        {
            get
            {
                var ret = heap.ToArray();
                Array.Sort(ret, cmp);
                return ret;
            }
        }
    }
    #endregion
}

/// <summary>
/// SEGTREEは1-BASE運用でございます
/// よろしくおねがいします
/// </summary>
/// <typeparam name="T"></typeparam>
class Segtree<T>
{
    int n;//高さ
    T[] tree;//本体
    Func<T, T, T> f;//更新関数。a -> b -> ab使ったなにか
    T exnum;//初期値
    int count;
    /// <summary>
    /// !!!WARNING!!! 1-BASEです。
    /// </summary>
    /// <param name="m">最大値。200001とか入れておくとよい</param>
    /// <param name="f">２引数の関数</param>
    /// <param name="ex">葉に書いてある値の初期値。fの関数に影響を与えない数値、零元とかにしておくべき。バグり散らかす。</param>
    public Segtree(int m, Func<T, T, T> f, T ex)
    {
        this.count = 0;
        this.f = f;
        this.exnum = ex;
        n = 1;
        while (n < m) n <<= 1;

        tree = new T[(n << 1) - 1];
        for (int i = 0; i < tree.Length; i++) tree[i] = ex;
    }
    public Segtree(int m, T ini, Func<T, T, T> f, T ex) : this(m, f, ex)
    {
        this.count = 0;
        for (int i = 0; i < m; ++i) tree[i + n - 1] = ini;
        all_update();
    }

    /// <summary>
    /// j番目の値をxにする。計算し直さないので、
    /// 入れ替えた後はall_update();を使おう
    /// </summary>
    /// <param name="j">番目</param>
    /// <param name="x">更新後の値</param>
    public void assign_without_update(int j, T x)
    {
        tree[j + n - 1] = x;
    }
    /// <summary>
    /// j番目の値をxにする。計算し直すので、ちょっと計算時間がかかる
    /// </summary>
    /// <param name="j">番目</param>
    /// <param name="x">更新後の値</param>
    public void update(int j, T x)//j番目をxにする
    {
        int i = j + n - 1;
        tree[i] = x;
        while (i > 0)
        {
            i = (i - 1) >> 1;
            tree[i] = f(tree[(i << 1) + 1], tree[(i << 1) + 2]);
        }
        this.count++;
    }

    /// <summary>
    /// 木を全部計算し直す。多分NlogN。違うかも知れないから
    /// よかったら教えて
    /// </summary>
    public void all_update()
    {
        for (int i = n - 2; i >= 0; i--)
            tree[i] = f(tree[(i << 1) + 1], tree[(i << 1) + 2]);
    }
    public T look(int i) { return tree[i + n - 1]; }

    /// <summary>
    /// j番目を消す。
    /// </summary>
    /// <param name="j"></param>
    public void delete(int j)
    {
        int i = j + n - 1;
        tree[i] = exnum;
        int moved = 0;

        while (true)
        {
            tree[i + 1] = tree[i];
            T check = tree[i];
            moved++;
            if (moved + j + 2 > count)
            {
                break;
            }

        }
        all_update();
    }


    // [s, t)
    /// <summary>
    /// s番目からt番目までの結果を返す。
    /// これも当然のように1-BASE.
    /// </summary>
    /// <param name="s"></param>
    /// <param name="t"></param>
    /// <returns></returns>
    public T run(int s, int t) { return query(s, t, 0, 0, n); }
    T query(int s, int t, int k, int l, int r)
    {
        if (r <= s || t <= l) return exnum;
        if (s <= l && r <= t) return tree[k];

        return f(query(s, t, (k << 1) + 1, l, (l + r) >> 1), query(s, t, (k + 1) << 1, (l + r) >> 1, r));
    }
}