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

namespace Codeforces
{
    class E
    {
        private static ThreadStart  s_threadStart = new E().Go;

        class Point
        {
            public int X, Y;
            public bool Keep;
        }

        long[] F;

        private void Go()
        {
            long mod = 1000000007;

            int n = GetInt();
            Point[] points = new Point[n];
            for (int i = 0; i < n; i++)
            {
                points[i] = new Point() { X = GetInt(), Y = GetInt() };
            }

            F = new long[2*n + 1];
            F[0] = 1;
            for (int i = 1; i <= 2 * n; i++)
                F[i] = (F[i - 1] * i) % mod;

            Dictionary<int, List<int>> xDict = new Dictionary<int, List<int>>();
            Dictionary<int, List<int>> yDict = new Dictionary<int, List<int>>();
            for(int i = 0; i < n; i++)
            {
                List<int> list;
                if (!xDict.TryGetValue(points[i].X, out list))
                    list = xDict[points[i].X] = new List<int>();

                list.Add(i);

                if (!yDict.TryGetValue(points[i].Y, out list))
                    list = yDict[points[i].Y] = new List<int>();

                list.Add(i);
            }

            long ans = 1;

            Queue<int> queue = new Queue<int>();
            while (xDict.Count > 0)
            {
                int k = 0;
                int m = 0;
                var pair = xDict.First();
                queue.Enqueue(pair.Value[0]);

                HashSet<int> xDir = new HashSet<int>();
                HashSet<int> yDir = new HashSet<int>();
                HashSet<int> pSet = new HashSet<int>();

                while (queue.Count > 0)
                {
                    int pp = queue.Dequeue();
                    Point point = points[pp];
                    pSet.Add(pp);
                    xDir.Add(point.X);
                    yDir.Add(point.Y);
                    if (xDict.ContainsKey(point.X))
                    {
                        foreach (int z in xDict[point.X])
                            if (z != pp)
                                queue.Enqueue(z);
                    }
                    if (yDict.ContainsKey(point.Y))
                    {
                        foreach (int z in yDict[point.Y])
                            if (z != pp)
                                queue.Enqueue(z);
                    }
                    xDict.Remove(point.X);
                    yDict.Remove(point.Y);
                }

                ans *= Bin(xDir.Count() + yDir.Count(), pSet.Count(), mod);
                ans %= mod;
            }

            Wl(ans);
        }

        long Bin(long n, long k, long mod)
        {
            long ans = 0;
            for (int i = 0; i <= k; i++)
            {
                long add = F[n];
                add *= Inv(F[i], mod);
                add %= mod;
                add *= Inv(F[n - i], mod);
                add %= mod;
                ans += add;
                ans %= mod;
            }
            return ans;
        }

        public static long Pow(long a, long n, long mod)
        {
            long res = 1L;
            while (n > 0)
            {
                if ((n & 1) != 0)
                    res = (res * a) % mod;
                a = (a * a) % mod;
                n >>= 1;
            }
            return res;
        }

        public static long Inv(long a, long mod)
        {
            return Pow(a, mod - 2, mod);
        }

        #region Template

        private static StringBuilder output = new StringBuilder();

        public static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            output.Length = 0;
            Thread main = new Thread(new ThreadStart(s_threadStart), 512 * 1024 * 1024);
            timer.Start();
            main.Start();
            main.Join();
            Console.Write(output);
            timer.Stop();
            Console.Error.WriteLine(timer.ElapsedMilliseconds);
        }

        private static IEnumerator<string> ioEnum;
        private static string GetString()
        {
            do
            {
                while (ioEnum == null || !ioEnum.MoveNext())
                {
                    ioEnum = Console.ReadLine().Split().AsEnumerable().GetEnumerator();
                }
            } while (string.IsNullOrEmpty(ioEnum.Current));

            return ioEnum.Current;
        }

        private static int GetInt()
        {
            return int.Parse(GetString());
        }

        private static long GetLong()
        {
            return long.Parse(GetString());
        }

        private static double GetDouble()
        {
            return double.Parse(GetString());
        }

        private static List<int> GetIntArr(int n)
        {
            List<int> ret = new List<int>(n);
            for (int i = 0; i < n; i++)
            {
                ret.Add(GetInt());
            }
            return ret;
        }

        private static void Wl<T>(T o)
        {
            W(o);
            output.Append(Console.Out.NewLine);
        }

        private static void Wl<T>(IEnumerable<T> enumerable)
        {
            W(enumerable);
            output.Append(Console.Out.NewLine);
        }

        private static void W<T>(T o)
        {
            if (o is double)
            {
                Wd((o as double?).Value, "");
            }
            else if (o is float)
            {
                Wd((o as float?).Value, "");
            }
            else
                output.Append(o.ToString());
        }

        private static void W<T>(IEnumerable<T> enumerable)
        {
            W(string.Join(" ", enumerable.Select(e => e.ToString()).ToArray()));
        }

        private static void Wd(double d, string format)
        {
            W(d.ToString(format, CultureInfo.InvariantCulture));
        }

        #endregion
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

public class NetworkXOneTimePad
{
    public static void Main()
    {
        string str = Console.ReadLine();
        string[] values = str.Split(' ');
        int a = int.Parse(values[0]);
        int b = int.Parse(values[1]);
        str = Console.ReadLine();
        int x=0,y=0;
        List<KeyValuePair<int, int>> lst = new List<KeyValuePair<int, int>>();
        lst.Add(new KeyValuePair<int,int>(0,0));

        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == 'R')
            {
                x++;
            }
            else if (str[i] == 'L')
            {
                x--;
            }
            else if (str[i] == 'U')
            {
                y++;
            }
            else
            {
                y--;
            }
            lst.Add(new KeyValuePair<int,int>(x,y));
        }
        int px=x,py=y,ans=0;
        foreach (var kv in lst)
        {

            if(px!=0 && py!=0 && ((a-kv.Key)%px ==0) && ((b-kv.Value)%py==0) &&((a-kv.Key)/px ==(b-kv.Value)/py)&& (b-kv.Value)/p>=0)
            {
                ans=1;
                break;
            }
            else if (px == 0 && py == 0 && (a == kv.Key) && (b == kv.Value))
            {
               ans=1;
                break;
            }
            else if (px == 0 && (a == kv.Key) && ((b-kv.Value)%py ==0) && (b-kv.Value)/p>=0)
            {
                ans=1;
                break;
            }
            else if (py == 0 && (b == kv.Value) && ((a - kv.Key) % px == 0) &&(a-kv.Key)/p >=0)
            {
                ans=1;
                break;
            }
        }
        if(ans==0)Console.WriteLine("No");
else Console.WriteLine("Yes");
        Console.ReadLine();
    }
}


/*using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

public class NetworkXOneTimePad
{
    public static void Main()
    {
        int n = 100;
        int[,] G = new int[n+1,n+1];
        Dictionary<int, bool> d = new Dictionary<int, bool>();
        List<KeyValuePair<int, int>> temp = new List<KeyValuePair<int, int>>();
        d.Add(1,true);
        KeyValuePair<int, int> ns;
        while (d.Count != n)
        {
            foreach(var current in d)
            {
                for (int i = 1; i < n + 1; i++)
                {
                    if (!d.ContainsKey(i) && G[current.Key, i] != 0)
                    {
                        temp.Add(new KeyValuePair<int,int>(i,G[current.Key,i]));
                    }
                }
            }
            temp.Sort();
        }
    }
}*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

public class NetworkXOneTimePad
{
    public static void Main()
    {
        string str = Console.ReadLine();
        string[] values = str.Split(' ');
        int a = int.Parse(values[0]);
        int b = int.Parse(values[1]);
        str = Console.ReadLine();
        int x=0,y=0;
        List<KeyValuePair<int, int>> lst = new List<KeyValuePair<int, int>>();
        lst.Add(new KeyValuePair<int,int>(0,0));

        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == 'R')
            {
                x++;
            }
            else if (str[i] == 'L')
            {
                x--;
            }
            else if (str[i] == 'U')
            {
                y++;
            }
            else
            {
                y--;
            }
            lst.Add(new KeyValuePair<int,int>(x,y));
        }
        int px=x,py=y,ans=0;
        foreach (var kv in lst)
        {

            if(px!=0 && py!=0 && ((a-kv.Key)%px ==0) && ((b-kv.Value)%py==0) &&((a-kv.Key)/px ==(b-kv.Value)/py)&& (b-kv.Value)/py>=0)
            {
                ans=1;
                break;
            }
            else if (px == 0 && py == 0 && (a == kv.Key) && (b == kv.Value))
            {
               ans=1;
                break;
            }
            else if (px == 0 && (a == kv.Key) && ((b-kv.Value)%py ==0) && (b-kv.Value)/py>=0)
            {
                ans=1;
                break;
            }
            else if (py == 0 && (b == kv.Value) && ((a - kv.Key) % px == 0) &&(a-kv.Key)/px >=0)
            {
                ans=1;
                break;
            }
        }
        if(ans==0)Console.WriteLine("No");
else Console.WriteLine("Yes");
        Console.ReadLine();
    }
}


using System;

namespace MakingSequences
{
    class MakingSequences
    {
        static void Main(string[] args)
        {
            ulong w, m, k, pow10, cost = 0, rem = 0, count, lengthPow10, lastPow10, diff;
            string[] input;

            input = Console.ReadLine().Split();
            w = ulong.Parse(input[0]);
            m = ulong.Parse(input[1]);
            k = ulong.Parse(input[2]);

            lengthPow10 = (ulong)input[1].Length;
            cost = lengthPow10 * k;
            pow10 = (ulong)Math.Pow(10, lengthPow10);
            rem = (pow10 - m) * k;

            if (rem > w)
                Console.WriteLine(w / cost);
            else
            {
                count = rem / cost;
                w -= rem;

                while (true)
                {
                    lastPow10 = pow10;
                    lengthPow10++;
                    cost = lengthPow10 * k;
                    pow10 = (ulong)Math.Pow(10, lengthPow10);
                    diff = pow10 - lastPow10;
                    rem = diff * cost;

                    if (rem < w)
                    {
                        count += (rem / cost);
                        w -= rem;
                    }
                    else
                    {
                        count += (w / cost);
                        break;
                    }
                }

                Console.WriteLine(count);
            }
        }
    }
}


using System;
using System.Text;
using System.Collections.Generic;
using System.IO;

namespace С1
{
    class Program
    {
        static bool isFileIO = false;

        static string[] lines;
        static int pointer = 0;

        static void Main(string[] args)
        {
            if (isFileIO)
            {
                lines = File.ReadAllLines("input.txt");
            }
            ClearFile();
            Solve();
        }

        static string ReadLine()
        {
            if (isFileIO)
            {
                return lines[pointer++];
            }
            else
            {
                return Console.ReadLine();
            }
        }

        static void ClearFile()
        {
            File.WriteAllText("output.txt", "");
        }

        static void WriteLine(string str)
        {
            if (isFileIO)
            {
                File.AppendAllText("output.txt", str + "\n");
            }
            else
            {
                Console.WriteLine(str);
            }
        }

        static void Solve()
        {
            long w;
            long m;
            long k;

            string[] s = Console.ReadLine().Split(' ');
            w = long.Parse(s[0]);
            m = long.Parse(s[1]);
            k = long.Parse(s[2]);

            long balls = w / k;
            //Console.WriteLine(naive(balls, m));
            Console.WriteLine(real(balls, m));
        }

        static long summ(long a)
        {
            string s = a + "";
            return s.Length;
        }

        static long real(long balls, long m)
        {
            int n = 18;
            long first = summ(m);
            long sec = 0;
            for (long i = 1; i < n; i++)
            {
                long power = (long)Math.Pow(10, i);
                if(power >= m)
                {
                    sec = i;
                    break;
                }
            }

            List<long> longs = new List<long>();
            longs.Add(m);
            for (long i = sec; i < n; i++)
            {
                longs.Add((long)Math.Pow(10, i));
            }

            for (int i = 0; i < longs.Count; i++ )
            {
                //Console.WriteLine(longs[i]);
            }

            List<long> dl = new List<long>();

            List<long> points = new List<long>();
            long portion = first * ((long)Math.Pow(10, sec)-m);
            points.Add(portion);
            dl.Add(sec);
            for (long i = sec + 1; i < n; i++)
            {
                points.Add(i * ((long)Math.Pow(10, i) - (long)Math.Pow(10, i-1)));
                dl.Add(i);
            }

            for (int i = 0; i < points.Count; i++)
            {
                Console.WriteLine(points[i]);
            }

            long total = 0;
            for (int i = 0; i < points.Count; i++ )
            {
                if (balls >= points[i])
                {
                    total += points[i]/dl[i];
                    balls -= points[i];
                }
                else
                {
                    long diff = balls / dl[i];
                    total += diff;
                    balls -= diff * dl[i];
                }
            }

            //Console.WriteLine(total);

            return total;
        }

        static long naive(long balls, long m)
        {
            long total = 0;
            long i = m;
            long c = 0;
            while(total<balls)
            {
                if (total + summ(i) <= balls)
                {
                    total += summ(i);
                    Console.WriteLine(i + " " + summ(i));
                    i++;
                    c++;
                }
                else
                {
                    break;
                }
            }
            return c;
        }

    }

}

/*
1 1
#
1
1 1
*/


using System;
namespace CodeForces
{
    class Solution
    {
        static ulong S(UInt64 n){
            ulong count = 0;
            while (n > 0){
                n /= 10;
                count += 1;
            }
            return count;
        }
        static UInt64 MinNum(ulong n){
            UInt64 res = 1;
            UInt64 num = 10;
            n -= 1;
            while (n > 0){
                if (n % 2 == 1){
                    res *= num;
                }
                num *= num;
                n /= 2;
            }
            return res;
        }
        static UInt64 MaxNum(ulong n){
            return MinNum(n + 1) - 1;
        }
        static UInt64 cost(UInt64 l, UInt64 r, UInt64 k){
            UInt64 c  = 0;
            UInt64 sl = S(l);
            while (r > MaxNum(sl)){
                c += (MaxNum(sl) - l + 1) * sl * k;
                l = MinNum(sl + 1);
                sl +=1;
            }
            c += (r - l + +1)*sl*k;
            return c;
        }

        static void Main()
        {
            UInt64 w, m, k;
            string[] s = Console.ReadLine().Split();
            w = UInt64.Parse(s[0]);
            m = UInt64.Parse(s[1]);
            k = UInt64.Parse(s[2]);

            //Console.WriteLine(cost(5, 10, 14));

            if (S(m) * k > w)
            {
                Console.WriteLine(0);
            }else{
                UInt64 diff = 100;
                UInt64 r = m + diff;
                while (cost(m, r, k) < w)
                {
                    diff += diff;
                    k += diff;
                }

                UInt64 l = m;

                while (r - l > 1)
                {
                    UInt64 med = l + (r - l) / 2;
                    UInt64 c = cost(m, med, k);
                    if (c == w)
                    {
                        r = med;
                        break;
                    }
                    else if (c > w)
                    {
                        r = med;
                    }
                    else l = med;
                }
                if (cost(m, r, k) <= w)  Console.WriteLine(r - m + 1);
                else Console.WriteLine(l - m + 1);
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeForces
{
    class Program
    {
        static void Main(string[] args)
        {
            var line = Console.ReadLine().Split(' ');
            var W = long.Parse(line[0]);
            var M = long.Parse(line[1]);
            var K = long.Parse(line[2]);

            var count = W / K;
            long ans = 0;
            var digits = (long)Math.Floor(Math.Log10(M) + 1);

            while (count >= digits)
            {
                digits = (long)Math.Floor(Math.Log10(M) + 1);
                if (count - digits < 0)
                    break;

                var times = (long)Math.Pow(10, digits) - M;

                if (count >= times * digits)
                {
                    //Batch
                    count -= times * digits;
                    M = (long)Math.Pow(10, digits);
                    ans += times;
                }
                else
                {
                    times = count / digits;

                    //One Time
                    //count -= digits;
                    //M++;
                    ans += times;
                }
            }

            Console.WriteLine(ans);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeForces
{
    class Program
    {
        static void Main(string[] args)
        {
            var line = Console.ReadLine().Split(' ');
            var W = long.Parse(line[0]);
            var M = long.Parse(line[1]);
            var K = long.Parse(line[2]);
            var count = W / K;
            long ans = 0;

            while (count != 0)
            {
                var digits = (long)Math.Floor(Math.Log10(M) + 1);
                if (count - digits < 0)
                    break;

                var times = digits * 10 - M + 1;
                if (count >= times * digits)
                {
                    //Batch
                    count -= times * digits;
                    M = M + digits * 10;
                    ans += times;
                }
                else
                {
                    //One Time
                    count -= digits;
                    M++;
                    ans++;
                }
            }

            Console.WriteLine(ans);
        }
    }
}


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

namespace B
{
	class Program
	{
		static void Main(string[] args)
		{
			//Console.SetIn(File.OpenText("in.txt"));
			var d = Console.ReadLine().Split(' ').Select(i => long.Parse(i)).ToArray();
			var w = d[0];
			var m = d[1];
			var k = d[2];

			long cur = getCount(m);
			var min = m;
			long sum = 0;
			while (true)
			{
				var next = cur + 1;
				long max = pow(cur);

				var diff = max - min;

				if (diff * k * cur <= w)
				{
					w -= diff * k * cur;
					cur++;
					min = max;
					sum += diff;

					continue;
				}

				var l = min;
				var r = max - 1;
				while (true)
				{
					if (l == r)
					{
						break;
					}

					var p = l + (r - l + 1) / 2;
					diff = p - min;
					if (diff * k * cur <= w)
					{
						l = p;
					}
					else
					{
						r = p - 1;
					}
				}
				var added = l - min;
				if (k * cur * l <= w)
				{
					added++;
				}
				//var cost = added * k * cur;
				//w -= cost;

				sum += added;
				break;
			}
			Console.WriteLine(sum);

		}

		static long pow(long p)
		{
			long a = 1;
			for (int i = 0; i < p; i++)
			{
				a *= 10;
			}

			return a;
		}

		static long getCount(long i)
		{
			long c = 0;
			while (true)
			{
				if (i == 0)
				{
					break;
				}
				i = i / 10;
				c++;
			}

			return c;
		}
	}
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    public void Solve()
    {
        long w = ReadLong();
        long m = ReadLong();
        long k = ReadLong();

        int n = m.ToString().Length;
        if (n * k > w)
        {
            Write(0);
            return;
        }
        w -= n * k;

        long d = 0;
        while (d <= m)
            d = d * 10 + 9;

        long x = m;
        while (true)
        {
            if (w < n * k)
                break;
            long v = Math.Min(d - x, w / n / k);
            w -= v * n * k;
            x += v;
            d = d * 10 + 9;
            n++;
        }

        Write(x - m + 1);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("cycle.in");
        //writer = new StreamWriter("cycle.out");
#endif
        try
        {
            //            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //            thread.Start();
            //            thread.Join();
            new Solver().Solve();
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            Console.WriteLine(ex);
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write

    private static Queue<string> currentLineTokens = new Queue<string>();

    private static string[] ReadAndSplitLine()
    {
        return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public static string ReadToken()
    {
        while (currentLineTokens.Count == 0)
            currentLineTokens = new Queue<string>(ReadAndSplitLine());
        return currentLineTokens.Dequeue();
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray()
    {
        return ReadAndSplitLine().Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray()
    {
        return ReadAndSplitLine().Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray()
    {
        return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows);
        int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = new int[numberOfRows];
            for (int j = 0; j < numberOfRows; j++)
                ret[i][j] = matrix[j][i];
        }
        return ret;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
            lines[i] = reader.ReadLine().Trim();
        return lines;
    }

    public static void WriteArray<T>(IEnumerable<T> array)
    {
        writer.WriteLine(string.Join(" ", array));
    }

    public static void Write(params object[] array)
    {
        WriteArray(array);
    }

    public static void WriteLines<T>(IEnumerable<T> array)
    {
        foreach (var a in array)
            writer.WriteLine(a);
    }

    class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }

    #endregion
}


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

namespace _373_B
{
  class Program
  {
    static void Main(string[] args)
    {

      long[] input = Console.ReadLine().Split().Select(long.Parse).ToArray();

      long w = input[0];
      long m = input[1];
      long k = input[2];

      long overallCount = 0;
      long cost = 0;
      long current = m;

      while (cost < w)
      {
        int unitLength = current.ToString().Count();
        long unitCost = ((long)unitLength)*k;
        var biggest = long.Parse(new string('9', unitLength));
        long count = biggest - current + 1;
        long currentCost = count*unitCost;
        if (cost + currentCost <= w)
        {
          cost += currentCost;
          overallCount += count;
          current = biggest + 1;
        }
        else
        {
          long countmin = (w - cost)/unitCost;
          overallCount += countmin;
          Console.WriteLine(overallCount);
          return;
        }
      }
      Console.WriteLine(overallCount);
    }
  }
}


using System;
using System.Collections.Generic;
using System.Linq;
using CompLib.Util;

public class Program
{
    int N, M;
    int[] K;
    int[] D, T;

    List<int>[] S;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        M = sc.NextInt();

        K = sc.IntArray();
        S = new List<int>[400001];
        for (int i = 0; i <= 400000; i++)
        {
            S[i] = new List<int>();
        }
        for (int i = 0; i < M; i++)
        {
            int d = sc.NextInt();
            int t = sc.NextInt() - 1;
            S[d].Add(t);
        }

        /*
         * 毎日1B獲得
         *
         * n種類
         * 通常2B
         * セール1B
         *
         * タイプiをK_i個
         *
         * m個
         *
         * タイプt_iがd_iにセール
         *
         * 全部買う　最小日数
         */

        /*
         * i日で達成できるか?
         *
         * 最後から見る
         *
         */
        int ok = 400000;
        int ng = 0;
        while (ok - ng > 1)
        {
            int mid = (ok + ng) / 2;
            if (F(mid)) ok = mid;
            else ng = mid;
        }
        Console.WriteLine(ok);

    }

    // t日でできるか?
    bool F(int t)
    {
        int[] tmp = new int[N];
        Array.Copy(K, tmp, N);
        int B = 0;
        for (int i = 1; i <= t; i++)
        {
            B++;
            foreach (var type in S[i])
            {
                int min = Math.Min(tmp[type], B);
                tmp[type] -= min;
                B -= min;
            }
        }
        long sum = 0;
        foreach (var i in tmp)
        {
            sum += i;
        }

        return sum * 2 <= B;
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public string ReadLine()
        {
            _index = _line.Length;
            return Console.ReadLine();
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SB = System.Text.StringBuilder;
//using System.Threading.Tasks;
//using System.Text.RegularExpressions;
//using System.Globalization;
//using System.Diagnostics;
using static System.Console;
using System.Numerics;
using static System.Math;
using pair = Pair<int, int>;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    readonly Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;
    readonly int dom = 998244353;
    bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (b.CompareTo(a) < 0) { a = b; return true; } return false; }

    bool calc(int day, int[] K, List<int>[] L, int Sum)
    {
        int used = 0;
        int money = day;
        for (int i = day - 1; i >= 0; i--)
        {
            if (i < L.Length)
            {
                foreach (var v in L[i])
                {
                    int buy = Min(K[v], money);
                    money -= buy;
                    K[v] -= buy;
                    used += buy;
                }
            }
            money = Min(i, money);
        }

        int remain = Sum - used;

        if (day == 7)
        {
            WriteLine(used);
        }
        return remain * 2 <= (day - used);

    }
    void solve()
    {
        int N = cin.nextint;
        int M = cin.nextint;
        var K = cin.scanint;

        var L = new List<int>[N];
        for (int i = 0; i < L.Length; i++)
        {
            L[i] = new List<int>();
        }
        for (int i = 0; i < M; i++)
        {
            L[cin.nextint - 1].Add(cin.nextint - 1);
        }
        int Sum = K.Sum();

        int ng = 0;
        int ok = Sum * 2;
        while (ok - ng > 1)
        {
            int mid = (ok + ng) / 2;

            var Z = new int[N];
            for (int i = 0; i < Z.Length; i++)
            {
                Z[i] = K[i];
            }

            if (calc(mid, Z, L, Sum))
            {
                ok = mid;
            }
            else
            {
                ng = mid;
            }
        }

        WriteLine(ok);

    }

}

static class Ex
{
    public static void join<T>(this IEnumerable<T> values, string sep = " ") => WriteLine(string.Join(sep, values));
    public static string concat<T>(this IEnumerable<T> values) => string.Concat(values);
    public static string reverse(this string s) { var t = s.ToCharArray(); Array.Reverse(t); return t.concat(); }

    public static int lower_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) < 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
    public static int upper_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) <= 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
}

class Pair<T, U> : IComparable<Pair<T, U>> where T : IComparable<T> where U : IComparable<U>
{
    public T f; public U s;
    public Pair(T f, U s) { this.f = f; this.s = s; }
    public int CompareTo(Pair<T, U> a) => f.CompareTo(a.f) != 0 ? f.CompareTo(a.f) : s.CompareTo(a.s);
    public override string ToString() => $"{f} {s}";
}

class Scanner
{
    string[] s; int i;
    readonly char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan => ReadLine().Split();
    public int[] scanint => Array.ConvertAll(scan, int.Parse);
    public long[] scanlong => Array.ConvertAll(scan, long.Parse);
    public double[] scandouble => Array.ConvertAll(scan, double.Parse);
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint => int.Parse(next);
    public long nextlong => long.Parse(next);
    public double nextdouble => double.Parse(next);
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SB = System.Text.StringBuilder;
//using System.Threading.Tasks;
//using System.Text.RegularExpressions;
//using System.Globalization;
//using System.Diagnostics;
using static System.Console;
using System.Numerics;
using static System.Math;
using pair = Pair<int, int>;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    readonly Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;
    readonly int dom = 998244353;
    bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (b.CompareTo(a) < 0) { a = b; return true; } return false; }

    bool calc(int day, int[] K, List<int>[] L, int Sum)
    {
        int used = 0;
        int money = day;
        for (int i = day - 1; i >= 0; i--)
        {
            if (i < L.Length)
            {
                foreach (var v in L[i])
                {
                    int buy = Min(K[v], money);
                    money -= buy;
                    K[v] -= buy;
                    used += buy;
                }
            }
            money = Min(i, money);
        }

        int remain = Sum - used;

        return remain * 2 <= (day - used);

    }
    void solve()
    {
        int N = cin.nextint;
        int M = cin.nextint;
        var K = cin.scanint;

        var L = new List<int>[N];
        for (int i = 0; i < L.Length; i++)
        {
            L[i] = new List<int>();
        }
        for (int i = 0; i < M; i++)
        {
            L[cin.nextint - 1].Add(cin.nextint - 1);
        }
        int Sum = K.Sum();

        int ng = 0;
        int ok = Sum * 2;
        while (ok - ng > 1)
        {
            int mid = (ok + ng) / 2;

            var Z = new int[N];
            for (int i = 0; i < Z.Length; i++)
            {
                Z[i] = K[i];
            }

            if (calc(mid, Z, L, Sum))
            {
                ok = mid;
            }
            else
            {
                ng = mid;
            }
        }

        WriteLine(ok);

    }

}

static class Ex
{
    public static void join<T>(this IEnumerable<T> values, string sep = " ") => WriteLine(string.Join(sep, values));
    public static string concat<T>(this IEnumerable<T> values) => string.Concat(values);
    public static string reverse(this string s) { var t = s.ToCharArray(); Array.Reverse(t); return t.concat(); }

    public static int lower_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) < 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
    public static int upper_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) <= 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
}

class Pair<T, U> : IComparable<Pair<T, U>> where T : IComparable<T> where U : IComparable<U>
{
    public T f; public U s;
    public Pair(T f, U s) { this.f = f; this.s = s; }
    public int CompareTo(Pair<T, U> a) => f.CompareTo(a.f) != 0 ? f.CompareTo(a.f) : s.CompareTo(a.s);
    public override string ToString() => $"{f} {s}";
}

class Scanner
{
    string[] s; int i;
    readonly char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan => ReadLine().Split();
    public int[] scanint => Array.ConvertAll(scan, int.Parse);
    public long[] scanlong => Array.ConvertAll(scan, long.Parse);
    public double[] scandouble => Array.ConvertAll(scan, double.Parse);
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint => int.Parse(next);
    public long nextlong => long.Parse(next);
    public double nextdouble => double.Parse(next);
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Task
{
  static class Program
  {
    #region Read / Write
    static TextReader Reader;
    static TextWriter Writer;
    private static Queue<string> _currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return Reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (_currentLineTokens.Count == 0) _currentLineTokens = new Queue<string>(ReadAndSplitLine()); return _currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++) matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
      int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
      for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++) ret[i][j] = matrix[j][i]; }
      return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++) lines[i] = Reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { Writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array) Writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
      public new TValue this[TKey key]
      {
        get { return ContainsKey(key) ? base[key] : default(TValue); }
        set { base[key] = value; }
      }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++) ret[i] = new T(); return ret; }
    #endregion=

    public static bool NextPermutation(List<int> perm)
    {
      for (int i = perm.Count - 2; i >= 0; i--)
      {
        if (perm[i] < perm[i + 1])
        {
          int min = i + 1;
          for (int j = min; j < perm.Count; j++)
            if (perm[j] > perm[i] && perm[j] < perm[min])
              min = j;

          var tmp = perm[i];
          perm[i] = perm[min];
          perm[min] = tmp;
          perm.Reverse(i + 1, perm.Count - i - 1);
          return true;
        }
      }

      return false;
    }

    #region SegmentTree

    public static long SegmentTreeFunc(long a, long b)
    {
      return a + b;
    }

    public static void BuildSegmentTree(long[] a, long v, long tl, long tr)
    {
      if (tl == tr)
        t[v] = a[tl];
      else
      {
        long tm = (tl + tr) / 2;
        BuildSegmentTree(a, v * 2, tl, tm);
        BuildSegmentTree(a, v * 2 + 1, tm + 1, tr);
        t[v] = SegmentTreeFunc(t[v * 2], t[v * 2 + 1]);
      }
    }

    public static long QuerySegmentTree(long v, long tl, long tr, long l, long r)
    {
      if (l > r)
        return 0;
      if (l == tl && r == tr)
        return t[v];

      var tm = (tl + tr) / 2;
      var res = SegmentTreeFunc(QuerySegmentTree(v * 2, tl, tm, l, Math.Min(r, tm)), QuerySegmentTree(v * 2 + 1, tm + 1, tr, Math.Max(l, tm + 1), r));
      return res;
    }

    public static void UpdateSegmentTree(int v, int tl, int tr, int pos, int new_val)
    {
      if (tl == tr)
        t[v] = new_val;
      else
      {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
          UpdateSegmentTree(v * 2, tl, tm, pos, new_val);
        else
          UpdateSegmentTree(v * 2 + 1, tm + 1, tr, pos, new_val);
        t[v] = SegmentTreeFunc(t[v * 2], t[v * 2 + 1]);
      }
    }

    public static long[] t;

    #endregion

    private static readonly int modulus = 1000000007;
    // private static readonly int modulus1 = modulus - 1;

    public static long Pow(long a, long b)
    {
      long y = 1;

      while (true)
      {
        if ((b & 1) != 0)
          y = a * y % modulus;
        b = b >> 1;
        if (b == 0)
          return y;
        a = a * a % modulus;
      }
    }

    public static long ReversedNumbByPrimeModulo(long a)
    {
      return Pow(a, modulus - 2);
    }

    public static long FactByModulo(long a)
    {
      long ans = 1;

      while (a > 0)
      {
        ans = ans * a % modulus;
        a--;
      }

      return ans;
    }

    public static long nCkModulo(long n, long k)
    {
      if (k < n >> 1)
        k = n - k;

      long ans = 1;
      for (long i = n; i > k; i--)
        ans = ans * i % modulus;

      k = n - k;
      var fact = FactByModulo(k);
      var revFact = ReversedNumbByPrimeModulo(fact);

      ans = ans * revFact % modulus;

      return ans;
    }

    public static int maxForPrimeCalc = 1000000;
    public static List<int> primes = new List<int>(maxForPrimeCalc) {2};
    // public static int[] minPrimeDiv = new int[maxForPrimeCalc + 1];
    public static bool[] isPrime = new bool[maxForPrimeCalc + 1];

    public static void CalcPrimes()
    {
      isPrime[2] = true;
      for (var i = 4; i <= maxForPrimeCalc; i += 2)
      {
        isPrime[i] = false;
        // minPrimeDiv[i] = 2;
      }
      for (var i = 3; i <= maxForPrimeCalc; i += 2)
      {
        isPrime[i] = true;
      }

      for (var i = 3; i * i <= maxForPrimeCalc; i += 2)
      {
        if (isPrime[i])
        {
          // minPrimeDiv[i] = i;
          primes.Add(i);
          for (var j = i * i; j <= maxForPrimeCalc; j += i)
          {
            if (isPrime[j])
            {
              isPrime[j] = false;
              // minPrimeDiv[j] = i;
            }
          }
        }
      }
    }
    //
    // public static int[] PrimeDifferentDividersCountHash = new int[maxForPrimeCalc + 1];
    //
    // private static int PrimeDifferentDividersCount(long numb)
    // {
    //   if (numb == 1)
    //     return 0;
    //   if (isPrime[numb])
    //     return 1;
    //
    //   if (PrimeDifferentDividersCountHash[numb] > 0)
    //     return PrimeDifferentDividersCountHash[numb];
    //
    //   var divider = minPrimeDiv[numb];
    //   var prevNumb = numb / divider;
    //   var ans = PrimeDifferentDividersCount(prevNumb);
    //
    //   if (divider != minPrimeDiv[prevNumb])
    //   {
    //     ans += 1;
    //   }
    //
    //   PrimeDifferentDividersCountHash[numb] = ans;
    //
    //   return ans;
    // }

    // #region Heap
    //
    // public static void InsertElementInHeap(MyStruct value, MyStruct[] arr, ref int sizeOfTree)
    // {
    //   sizeOfTree++;
    //   arr[sizeOfTree] = value;
    //   HeapifyUp(sizeOfTree, arr);
    // }
    //
    // public static void HeapifyUp(int cur, MyStruct[] arr)
    // {
    //   while (true)
    //   {
    //     if (cur == 1)
    //     {
    //       return;
    //     }
    //
    //     var parent = cur >> 1;
    //
    //     if (arr[cur].Value < arr[parent].Value)
    //     {
    //       arr[cur].Value ^= arr[parent].Value;
    //       arr[parent].Value ^= arr[cur].Value;
    //       arr[cur].Value ^= arr[parent].Value;
    //
    //       // arr[cur].Index ^= arr[parent].Index;
    //       // arr[parent].Index ^= arr[cur].Index;
    //       // arr[cur].Index ^= arr[parent].Index;
    //
    //       cur = parent;
    //       continue;
    //     }
    //
    //     break;
    //   }
    // }
    //
    // public static MyStruct ExtractHeadOfHeap(MyStruct[] arr, ref int sizeOfTree)
    // {
    //   var extractedValue = arr[1];
    //   arr[1] = arr[sizeOfTree];
    //   sizeOfTree--;
    //   HeapifyDown(1, sizeOfTree, arr);
    //   return extractedValue;
    // }
    //
    // public static void HeapifyDown(int cur, int sizeOfTree, MyStruct[] arr)
    // {
    //   while (true)
    //   {
    //     var left = cur << 1;
    //     var right = left + 1;
    //     int smallestChild;
    //
    //     if (sizeOfTree < left)
    //     {
    //       return;
    //     }
    //
    //     if (sizeOfTree == left || arr[left].Value < arr[right].Value)
    //       smallestChild = left;
    //     else
    //       smallestChild = right;
    //
    //     if (arr[cur].Value > arr[smallestChild].Value)
    //     {
    //       arr[cur].Value ^= arr[smallestChild].Value;
    //       arr[smallestChild].Value ^= arr[cur].Value;
    //       arr[cur].Value ^= arr[smallestChild].Value;
    //
    //       // arr[cur].Index ^= arr[smallestChild].Index;
    //       // arr[smallestChild].Index ^= arr[cur].Index;
    //       // arr[cur].Index ^= arr[smallestChild].Index;
    //
    //       cur = smallestChild;
    //       continue;
    //     }
    //
    //     break;
    //   }
    // }
    //
    // #endregion

    #region Sorted Set

    public class LowerBoundSortedSet<T> : SortedSet<T>
    {
      private ComparerDecorator<T> _comparerDecorator;
      private class ComparerDecorator<T> : IComparer<T>
      {
        private IComparer<T> _comparer;
        public T LowerBound { get; private set; }
        public T HigherBound { get; private set; }
        private bool _reset = true;
        public void Reset()
        {
          _reset = true;
        }
        public ComparerDecorator(IComparer<T> comparer)
        {
          _comparer = comparer;
        }
        public int Compare(T x, T y)
        {
          int num = _comparer.Compare(x, y);
          if (_reset)
          {
            LowerBound = y;
          }
          if (num >= 0)
          {
            LowerBound = y;
            _reset = false;
          }
          if (num <= 0)
          {
            HigherBound = y;
            _reset = false;
          }
          return num;
        }
      }
      public LowerBoundSortedSet()
        : this(Comparer<T>.Default) {}
      public LowerBoundSortedSet(IComparer<T> comparer)
        : base(new ComparerDecorator<T>(comparer))
      {
        _comparerDecorator = (ComparerDecorator<T>) Comparer;
      }
      public T FindLowerBound(T key)
      {
        _comparerDecorator.Reset();
        this.Contains<T>(key);
        return _comparerDecorator.LowerBound;
      }
      public T FindHigherBound(T key)
      {
        _comparerDecorator.Reset();
        this.Contains<T>(key);
        return _comparerDecorator.HigherBound;
      }
    }

    #endregion

    static long GCD(long a, long b)
    {
      while (b > 0) {
        a %= b;
        a ^= b;
        b ^= a;
        a ^= b;
      }
      return a;
    }

    // private static List<int>[] _divs = new List<int>[100000 + 1];

    // private static void CalcDivs()
    // {
    //   for (var i = 0; i < _divs.Length; i++)
    //     _divs[i] = new List<int>();
    //
    //   for (var i = 1; i < _divs.Length; i++)
    //   {
    //     for (var j = i; j < _divs.Length; j += i)
    //       _divs[j].Add(i);
    //   }
    // }

    static void Main(string[] args)
    {
      Reader = new StreamReader(Console.OpenStandardInput());
      Writer = new StreamWriter(Console.OpenStandardOutput());

      // CalcPrimes();
      // CalcDivs();

      // var t = ReadInt();
      // for (var tmp = 0; tmp < t; tmp++)
      {
        Solve();
      }

      Reader.Close();
      Writer.Close();
    }

    static void Solve()
    {
      var n = ReadInt();

      var mod = 998244353L;
      var dp = new long[n + 1];
      dp[0] = 1;
      dp[1] = 1;
      var sum = 2L;
      for (var i = 2; i <= n; i++)
      {
        dp[i] = sum;
        dp[i] %= mod;

        var tmp = 0L;
        for (var j = 2; j <= i; j++)
          if (i % j == 0)
          {
            dp[i] += 1;
            dp[i] %= mod;
          }

        dp[i] += tmp;
        sum += dp[i];
        sum %= mod;
      }

      Write(dp[n]);
    }

    private static int RevertInd(int[] chainNumb, int ind, int[] inChainNumb, int permCount, List<List<int>> chains, out int oldInd)
    {
      var cn = chainNumb[ind];
      var inC = inChainNumb[ind];

      oldInd = inC - permCount % chains[cn].Count;
      if (oldInd < 0)
        oldInd += chains[cn].Count;
      return cn;
    }

    public struct MyStruct
    {
      public char Dir;
      public int X;
      public int Index;

      public MyStruct(char dir, int x, int index)
      {
        Dir = dir;
        X = x;
        Index = index;
      }
    }

    private static int gcdex (int a, int b, out int x, out int y) {
      if (a == 0) {
        x = 0; y = 1;
        return b;
      }
      int x1, y1;
      int d = gcdex (b%a, a, out x1, out y1);
      x = y1 - (b / a) * x1;
      y = x1;
      return d;
    }

    private static long GetNumb(Dictionary<char, int> letterDic, List<int> permutation, string s)
    {
      long res = 0;
      long mult = 1;
      for (var i = s.Length - 1; i >= 0; i--)
      {
        res += permutation[letterDic[s[i]]] * mult;

        mult *= 10;
      }

      return res;
    }

    static void Inc(this Dictionary<long, long> dict, long key, long addedValue)
    {
      if (dict.ContainsKey(key))
        dict[key] += addedValue;
      else
        dict[key] = addedValue;
    }

    static void Inc(this Dictionary<int, int> dict, int key, int addedValue)
    {
      if (dict.ContainsKey(key))
        dict[key] += addedValue;
      else
        dict[key] = addedValue;
    }
  }
}


using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApp9
{
    class Program
    {
        static long M = 1000000007l;

        static long getEvenCount(int n)
        {
            long nf = 1;
            for (int i = 2; i <= n; i++)
                nf = (nf * i) % M;

            var rf = new long[n + 1];
            var inf = new long[n + 1];
            rf[1] =  inf[0] = inf[1]  = 1;
            for(int i=2; i<= n; i++)
            {
                long a = M / i, b = M % i;
                rf[i] = M - (rf[b] * a) % M;
                inf[i] = (rf[i] * inf[i - 1]) % M;
            }

            long res = 0;
            for(int i=0; i<= n; i += 2)
                res = (res + nf* inf[i]* inf[n-i] ) % M;
            return res;
        }

        static void Main(string[] args)
        {
            var t = int.Parse(Console.ReadLine());
            for(int tc = 1; tc <= t; tc++)
            {
                var input = Console.ReadLine().Split(' ').Select(int.Parse).ToList();
                int n = input[0], k = input[1];
                if( k == 0)
                {
                    Console.WriteLine(1);
                    continue;
                }
                if( n%2 == 1)
                {
                    var even = getEvenCount(n);
                    long res = 1;
                    for (int i = 0; i < k; i++)
                        res = (res * (even+1)) % M;
                    Console.WriteLine(res);
                }
                else
                {
                    var even = getEvenCount(n);
                    var ev = new long[k + 1];
                    var ori = new long[k+1];
                    ev[0] = 1;
                    ori[0] = 1;
                    ori[1] = 2;
                    for (int i = 2; i <= n; i++)
                        ori[1] = (ori[1] * 2) % M;
                    for (int i = 2; i < k; i++)
                        ori[i] = (ori[i - 1] * ori[1]) % M;
                    for (int i = 1; i <= k; i++)
                        ev[i] = (ev[i - 1] * (even-1)) % M;
                    long res = ev[k];
                    for (int r1 = 0, r2 = k - 1; r1 < k; r1++, r2--)
                        res = (res + ev[r1] * ori[n * r2]) % M;
                    Console.WriteLine(res);
                }
            }
        }
    }
}


using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApp9
{
    class Program
    {
        static long M = 1000000007l;

        static long getEvenCount(int n)
        {
            long nf = 1;
            for (int i = 2; i <= n; i++)
                nf = (nf * i) % M;

            var rf = new long[n + 1];
            var inf = new long[n + 1];
            rf[1] =  inf[0] = inf[1]  = 1;
            for(int i=2; i<= n; i++)
            {
                long a = M / i, b = M % i;
                rf[i] = M - (rf[b] * a) % M;
                inf[i] = (rf[i] * inf[i - 1]) % M;
            }

            long res = 0;
            for(int i=0; i<= n; i += 2)
                res = (res + nf* inf[i]* inf[n-i] ) % M;
            return res;
        }

        static void Main(string[] args)
        {
            var t = int.Parse(Console.ReadLine());
            for(int tc = 1; tc <= t; tc++)
            {
                var input = Console.ReadLine().Split(' ').Select(int.Parse).ToList();
                int n = input[0], k = input[1];
                if( k == 0)
                {
                    Console.WriteLine(1);
                    continue;
                }
                if( n%2 == 1)
                {
                    var even = getEvenCount(n);
                    long res = 1;
                    for (int i = 0; i < k; i++)
                        res = (res * (even+1)) % M;
                    Console.WriteLine(res);
                }
                else
                {
                    var even = getEvenCount(n);
                    var orin = 1l;
                    for (int i = 1; i <= n; i++)
                        orin = (orin * 2) % M;
                    var dp = new long[k + 1, 2];
                    dp[0, 0] = 1;
                    dp[0, 1] = even-1;
                    for (int i=1; i <k; i++)
                    {
                        dp[i, 0] = (dp[i - 1, 0] * orin + dp[i-1,1]) % M ;
                        dp[i, 1] = (dp[i - 1, 1] * (even-1)) % M;
                    }
                    long res = (dp[k - 1, 0] + dp[k - 1, 1]) % M;
                    Console.WriteLine(res);
                }
            }

        }
    }
}