import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

public class C {

	static long x, k;
	static long mod = 1000000007;
	public static void main(String[] args) {
		JS in = new JS();
		x = in.nextLong();
		k = in.nextLong();

		if(x==0) {
			System.out.println(0);
			return;
		}

		long c = pow(2,k);
		if(c==0) c = mod;
		long sub = c-1;

		long low = ((c*(x%mod))%mod - sub);
		while(low < 0) low += mod;
		long res = ((low*2)%mod + sub)%mod;

		System.out.println(res);

	}

	static long pow(long a, long p) {
		if(p==0) return 1;
		if(p==1) return a;
		if(p%2==0) {
			long res = pow(a,p/2)%mod;
			return (res*res)%mod;
		}
		else {
			return (pow(a,p-1)*a)%mod;
		}

	}

	static class JS{
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public JS() {
			in = new BufferedInputStream(System.in, BS);
		}

		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class C {
	static final int M = 1000000007;

	public static void main(String[] args) throws IOException{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(in.readLine());

		long x = Long.parseLong(st.nextToken());
		if(x == 0){
			System.out.println(0);
			System.exit(0);
		}
		final long k = Long.parseLong(st.nextToken());
		x = x%M;

		long ans = (exp(2, k+1)*x - (exp(2, k) - 1))%M;
		if(ans < 0) ans += M;
		System.out.println(ans);
		/*
		for(long i = 1234567890; i < 1234567999; i++){
			ans = (exp(2, i+1)*x - (exp(2, i) - 1))%M;
			if(ans < 0) ans += M;
			System.out.println(ans);
		}
		/*
		System.out.println((k-1)/2);
		System.out.println(x);
		System.out.println(exp(2, k));
		System.out.println(exp(2, k+1));
		*/
	}

	public static long exp(long a, long n){
		if(n == 0) return 1;
		if(n == 1) return a%M;
		if(n%2 == 0) return exp((a*a)%M, n/2);
		else return (a*exp((a*a)%M, (n-1)/2))%M;
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long x = in.nextLong();
            long k = in.nextLong();
            long max2 = (((x % 1_000_000_007) * (pb(k))) % 1_000_000_007) % 1_000_000_007;
            long min2 = ((((x - 1) % 1_000_000_007) * pb(k)) % 1_000_000_007 + 1) % 1_000_000_007;
            if (x == 0) min2 = 0;
            out.println((max2 + min2) % 1_000_000_007);
        }

        long pb(long a) {
            if (a == 0) return 1;
            if (a == 1) return 2;
            long tmp = pb(a / 2);
            if (a % 2 == 0) return (tmp * tmp) % 1_000_000_007;
            return (((tmp * tmp) % 1_000_000_007) * 2) % 1_000_000_007;
        }

    }

    static class InputReader {
        private StringTokenizer tokenizer;
        private BufferedReader reader;

        public InputReader(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        private void fillTokenizer() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }

        public String next() {
            fillTokenizer();
            return tokenizer.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Solution {

    private static final long MODULUS = 1000000007;
    private static final boolean DEBUG = false;

    private static long modularPow(long base, long exponent, long modulus) {
        long result = 1;
        while (exponent > 0) {
            if (exponent % 2 == 1) {
               result = (result * base) % modulus;
            }
            exponent >>= 1;
            base = (base * base) % modulus;
        }
        return result;
    }

    public static void main(String[] args) throws FileNotFoundException {
        long beginTime = System.nanoTime();
        InputStream is = DEBUG ? new FileInputStream("resources/codeforcesedu43/ProblemC-1.in") : System.in;
        try (Scanner scanner = new Scanner(new BufferedReader(new InputStreamReader(is)))) {
            long x = scanner.nextLong();
            long k = scanner.nextLong();
            if (x != 0) {
                x = (2 * x - 1) % MODULUS;
                long twoPowK = modularPow(2, k, MODULUS);
                x = (x * twoPowK + 1) % MODULUS;
            }
            System.out.println(x % 1000000007);
        }
        System.err.println( "Done in " + ((System.nanoTime() - beginTime) / 1e9) + " seconds.");
    }
}


import java.math.BigInteger;
import java.util.*;
import java.io.*;

public class Contest {

	public static void main(String[] args)throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] s=br.readLine().split(" ");
		BigInteger x = new BigInteger(s[0]);
		BigInteger k = new BigInteger(s[1]);

		BigInteger mod = new BigInteger(String.valueOf((int) (Math.pow(10, 9) + 7)));

		BigInteger two = new BigInteger("2");
		BigInteger interm = two.modPow(k, mod);

		BigInteger res = interm.multiply(x).add(interm.multiply(x)).subtract(interm).add(BigInteger.ONE).mod(mod);

		if(x.equals(BigInteger.ZERO)) {
			System.out.println("0");
			return;
		}
		System.out.println(res);
	}

}


import javax.swing.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class A {

    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        long x = scanner.nextLong();
        long k = scanner.nextLong();
        if (x==0) {
            System.out.println("0");
            return;
        }
        BigInteger M = BigInteger.valueOf(1000_000_000L+7);
        BigInteger modus = BigInteger.valueOf(x).multiply(BigInteger.valueOf(2)).subtract(BigInteger.ONE).mod(M);
        BigInteger operandi = BigInteger.valueOf(2).modPow(BigInteger.valueOf(k), M);
        BigInteger result = modus.multiply(operandi).mod(M).add(BigInteger.ONE).mod(M);
        System.out.println(result);
    }

    public static long gcd(long a, long b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    public static long lcm(long a, long b, long gcd) {
        return a * (b / gcd);
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.awt.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
import java.util.StringTokenizer;

public class main {

	static long d,x,y;
	public static void main(String[] args) {
		FastScanner in = new FastScanner();

		long x = in.nextLong(), k = in.nextLong();

		long mod = 1000000007;

		long one = pow(2,k,mod);

		one %= mod;

		long two = (2*x)%mod-1;

		two %= mod;

		long ans = (one*two)%mod+1;

		ans %= mod;

		if(ans<0)
			ans += mod;

		if(x==0)
			System.out.println("0");
		else
			System.out.println(ans);

	}
	private static long pow(long a, long b, long mod) {
		if(b==0) return 1;

		if(b==1)
			return a;

		if(b%2==0)
			return pow((a*a)%mod,b/2,mod);
		else
			return (a*pow((a*a)%mod,(b-1)/2,mod))%mod;

	}

}

class FastScanner {
	BufferedReader br;
	StringTokenizer st;

	public FastScanner() {
		br = new BufferedReader(new InputStreamReader(System.in));
	}

	String next() {
		while (st == null || !st.hasMoreElements()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	int nextInt() {
		return Integer.parseInt(next());
	}

	long nextLong() {
		return Long.parseLong(next());
	}
}


import java.util.Scanner;

public class CF489_C {
	static long mod = 1000000007;

	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		long x = s.nextLong(), k = s.nextLong();
		if (x == 0) {
			System.out.println(0);
			return;
		}
		long max = x % mod;
		long temp = power(2, k, mod);
		temp %= mod;
		max = (max % mod) * (temp % mod);
		max %= mod;
		long min = max % mod;
		min = mod(min - (temp - 1));
		min %= mod;
		long num = mod(max - min + 1);
		long n = num % mod;
		n = (n % mod) * (min % mod + max % mod);
		n = n % mod;
		n %= mod;
		long ans = n % mod * modInverse(num, mod);
		System.out.println(ans % mod);

	}

	static long modInverse(long a, long m) {
		long m0 = m;
		long y = 0, x = 1;

		if (m == 1)
			return 0;

		while (a > 1) {
			// q is quotient
			long q = a / m;
			long t = m;

			// m is remainder now, process same as
			// Euclid's algo
			m = a % m;
			a = t;
			t = y;

			// Update y and x
			y = x - q * y;
			x = t;
		}

		// Make x positive
		if (x < 0)
			x += m0;

		return x;
	}

	static long mod(long val) {
		val %= mod;
		if (val < 0)
			val += mod;
		return val;
	}

	static long power(long x, long y, long p) {
		// Initialize result
		long res = 1;

		// Update x if it is more
		// than or equal to p
		x = x % p;

		while (y > 0) {
			// If y is odd, multiply x
			// with result
			if ((y & 1) == 1)
				res = (res * x) % p;

			// y must be even now
			// y = y / 2
			y = y >> 1;
			x = (x * x) % p;
		}
		return res;
	}

}


import java.io.*;
import java.util.StringTokenizer;

public class C {

    static final int MOD = (int)1e9 + 7;

    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

        long x = sc.nextLong(), k = sc.nextLong();
        if(x == 0)
            out.println(0);
        else
            out.println(((x % MOD * 2 - 1 + MOD) % MOD * modPow(2, k) % MOD + 1) % MOD);
        out.close();
    }

    static long modPow(long b, long e) {
        long res = 1;
        while(e > 0) {
            if((e & 1) == 1)
                res = res * b % MOD;
            b = b * b % MOD;
            e >>= 1;
        }

        return res;
    }

    static class Scanner
    {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

        public String next() throws IOException
        {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {return Integer.parseInt(next());}

        public long nextLong() throws IOException {return Long.parseLong(next());}

        public double nextDouble() throws IOException { return Double.parseDouble(next()); }

        public String nextLine() throws IOException {return br.readLine();}

        public boolean ready() throws IOException { return br.ready(); }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Rishabhdeep Singh
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int MOD = (int) 1e9 + 7;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            long x = in.nextLong(), k = in.nextLong();
            long res = Utilities.mul(x, Utilities.power(2, k + 1, MOD), MOD) % MOD - Utilities.power(2, k, MOD) + 1;
            while (res < 0) res += MOD;
            out.println(x == 0 ? 0 : res);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

    }

    static class Utilities {
        public static long mul(long x, long y, long mod) {
            return (x % mod) * (y % mod) % mod;
        }

        public static long power(long a, long k, long m) {
            long res = 1;
            while (k > 0) {
                if ((k & 1) != 0) {
                    res = mul(res, a, m);
                }
                a = mul(a, a, m);
                k >>= 1;
            }
            return res;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Rishabhdeep Singh
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int MOD = (int) 1e9 + 7;

        long power(long a, long k) {
            long res = 1;
            while (k > 0) {
                if ((k & 1) != 0) {
                    res = res * a % MOD;
                }
                a = a * a % MOD;
                k /= 2;
            }
            return res;
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            long x = in.nextLong(), k = in.nextLong();
            if (x == 0) {
                out.println(0);
                return;
            }
            long res = ((power(2, k + 1) % MOD) * (x % MOD)) % MOD;
            long temp = power(2, k);
            res = res - temp + 1;
            while (res < 0) res += MOD;
            out.println(res);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

        public void println(int i) {
            writer.println(i);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.util.*;
import java.io.*;

// Solution

public class Main
{
  public static void main (String[] argv)
  {
	  new Main();
  }

  boolean test = false;
  int n;

  long mod = 1000000007;
  public Main() {
	  FastReader in = new FastReader(new BufferedReader(new InputStreamReader(System.in)));
	  //FastReader in = new FastReader(new BufferedReader(new FileReader("Main.in")));
      long x = in.nextLong();
      long k = in.nextLong();

      if (x == 0) {
          System.out.println(0);
          return;
      }

      if (k == 0) {
          x %= mod;
          System.out.println((2*x%mod));
          return;
      }

      x %= mod;

      long f = pow(2, k);
      long ans = ((2 * f * x % mod - f + 1) % mod + mod) % mod;

      System.out.println(ans);

  }

  private long pow(long x, long y) {
      long ans = 1;
      while (y > 0) {
          if (y % 2 == 1)
              ans = ans * x % mod;
          x = x * x % mod;
          y /= 2;
      }
      return ans;
  }

  private long gcd(long x, long y) {
      if (y == 0) return x;
      return gcd(y, x % y);
  }
  private int max(int a, int b) {
      return a >  b ? a : b;
  }

  private int min(int a, int b) {
      return a >  b ? b : a;
  }

  static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader(BufferedReader in)
        {
            br = in;
        }

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    String line = br.readLine();
                    if (line == null || line.length() == 0) return "";
                    st = new StringTokenizer(line);
                }
                catch (IOException  e)
                {
                    return "";
                    //e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                return "";
                //e.printStackTrace();
            }
            return str;
        }
    }
}


import java.io.*;
import java.util.*;
/*
 * Heart beats fast
 * 		Colors and promises
 * 			How to be brave
 * 				How can I love when I am afraid...
 */
public class Main
{
	public static void main(String[] args)
	{
		long x=nl(),k=nl();
		if(x==0)
		{
			pr(0);
			exit();
		}
		x%=mod;
		pr((((x*powm(2,k+1,mod))%mod-powm(2,k,mod)+1)%mod+mod)%mod);
		System.out.print(output);
	}
	///////////////////////////////////////////
	///////////////////////////////////////////
	///template from here
	static class pair
	{
		long a, b;
		pair(){}
		pair(long c,long d){a=c;b=d;}
	}
	static interface combiner
	{
		public long combine(long a, long b);
	}
	static final int mod=1000000007;
	static final double eps=1e-9;
	static final long inf=100000000000000000L;
	static Reader in=new Reader();
	static StringBuilder output=new StringBuilder();
	static Random rn=new Random();
	static void reverse(int[]a){for(int i=0; i<a.length/2; i++){a[i]^=a[a.length-i-1];a[a.length-i-1]^=a[i];a[i]^=a[a.length-i-1];}}
	static void sort(int[]a)
	{
		int te;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
				a[i]^=a[te];
				a[te]^=a[i];
				a[i]^=a[te];
			}
		}
		Arrays.sort(a);
	}
	static void sort(long[]a)
	{
		int te;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
			a[i]^=a[te];
			a[te]^=a[i];
			a[i]^=a[te];
			}
		}
		Arrays.sort(a);
	}
	static void sort(double[]a)
	{
		int te;
		double te1;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
			te1=a[te];
			a[te]=a[i];
			a[i]=te1;
			}
		}
		Arrays.sort(a);
	}
	static void sort(int[][]a)
	{
		Arrays.sort(a, new Comparator<int[]>()
		{
			public int compare(int[]a,int[]b)
			{
				if(a[0]>b[0])
					return -1;
				if(b[0]>a[0])
					return 1;
				return 0;
			}
		});
	}
	static void sort(pair[]a)
	{
		Arrays.sort(a,new Comparator<pair>()
				{
			@Override
			public int compare(pair a,pair b)
			{
				if(a.a>b.a)
					return 1;
				if(b.a>a.a)
				return -1;
				return 0;
			}
				});
	}
	static int log2n(long a)
	{
		int te=0;
		while(a>0)
		{
			a>>=1;
			++te;
		}
		return te;
	}
	static class vector implements Iterable<Integer>
	{
		int a[],size;
		vector(){a=new int[10];size=0;}
		vector(int n){a=new int[n];size=0;}
		public void add(int b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
		@Override
		public Iterator<Integer> iterator() {
			Iterator<Integer> hola=new Iterator<Integer>()
					{
				int cur=0;
						@Override
						public boolean hasNext() {
							return cur<size;
						}
						@Override
						public Integer next() {
							return a[cur++];
						}
					};
			return hola;
		}
	}
	//output functions////////////////
	static void pr(Object a){output.append(a+"\n");}
	static void pr(){output.append("\n");}
	static void p(Object a){output.append(a);}
	static void pra(int[]a){for(int i:a)output.append(i+" ");output.append("\n");}
	static void pra(long[]a){for(long i:a)output.append(i+" ");output.append("\n");}
	static void pra(String[]a){for(String i:a)output.append(i+" ");output.append("\n");}
	static void pra(double[]a){for(double i:a)output.append(i+" ");output.append("\n");}
	static void sop(Object a){System.out.println(a);}
	static void flush(){System.out.println(output);output=new StringBuilder();}
	//////////////////////////////////
	//input functions/////////////////
	static int ni(){return Integer.parseInt(in.next());}
	static long nl(){return Long.parseLong(in.next());}
	static String ns(){return in.next();}
	static double nd(){return Double.parseDouble(in.next());}
	static int[] nia(int n){int a[]=new int[n];for(int i=0; i<n; i++)a[i]=ni();return a;}
	static int[] pnia(int n){int a[]=new int[n+1];for(int i=1; i<=n; i++)a[i]=ni();return a;}
	static long[] nla(int n){long a[]=new long[n];for(int i=0; i<n; i++)a[i]=nl();return a;}
	static String[] nsa(int n){String a[]=new String[n];for(int i=0; i<n; i++)a[i]=ns();return a;}
	static double[] nda(int n){double a[]=new double[n];for(int i=0; i<n; i++)a[i]=nd();return a;}
	//////////////////////////////////
	//some utility functions
	static void exit(){System.out.print(output);System.exit(0);}
	static int min(int... a){int min=a[0];for(int i:a)min=Math.min(min, i);return min;}
	static int max(int... a){int max=a[0];for(int i:a)max=Math.max(max, i);return max;}
	static int gcd(int... a){int gcd=a[0];for(int i:a)gcd=gcd(gcd, i);return gcd;}
	static long min(long... a){long min=a[0];for(long i:a)min=Math.min(min, i);return min;}
	static long max(long... a){long max=a[0];for(long i:a)max=Math.max(max, i);return max;}
	static long gcd(long... a){long gcd=a[0];for(long i:a)gcd=gcd(gcd, i);return gcd;}
	static String pr(String a, long b){String c="";while(b>0){if(b%2==1)c=c.concat(a);a=a.concat(a);b>>=1;}return c;}
	static long powm(long a, long b, long m)
	{long an=1;long c=a;while(b>0)
	{if(b%2==1)an=(an*c)%m;c=(c*c)%m;b>>=1;}return an;}
	static int gcd(int a, int b){if(b==0)return a;return gcd(b, a%b);}
	static long gcd(long a, long b){if(b==0)return a;return gcd(b, a%b);}
	static class Reader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public Reader() {
            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
            tokenizer = null;
        }
        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
    }
}


public class Main {

  private static void solve() {
    long x = nl();
    long k = nl();
    long mod = 1000000000 + 7;

    if (x == 0) {
      System.out.println(0);
    } else if (k == 0) {
      System.out.println(x * 2 % mod);

    } else {
      //x > 0, n > 0
      x %= mod;

      long a;
      a = (x - 1 + mod) * pow(2, k, mod) + 1;
      a %= mod;

      long b = x * pow(2, k, mod);
      b %= mod;

      System.out.println((a + b) % mod);
    }
  }

  public static long pow(long a, long n, long mod)
  {
//    a %= mod;
      long ret = 1; // 1%mod if mod=1,n=0
      int x = 63-Long.numberOfLeadingZeros(n);
      for(;x >= 0;x--){
          ret = ret * ret % mod;
          if(n<<~x<0)ret = ret * a % mod;
      }
      return ret;
  }

  public static void main(String[] args) {
    new Thread(null, new Runnable() {
      @Override
      public void run() {
        long start = System.currentTimeMillis();
        String debug = args.length > 0 ? args[0] : null;
        if (debug != null) {
          try {
            is = java.nio.file.Files.newInputStream(java.nio.file.Paths.get(debug));
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        }
        reader = new java.io.BufferedReader(new java.io.InputStreamReader(is), 32768);
        solve();
        out.flush();
        tr((System.currentTimeMillis() - start) + "ms");
      }
    }, "", 64000000).start();
  }

  private static java.io.InputStream is = System.in;
  private static java.io.PrintWriter out = new java.io.PrintWriter(System.out);
  private static java.util.StringTokenizer tokenizer = null;
  private static java.io.BufferedReader reader;

  public static String next() {
    while (tokenizer == null || !tokenizer.hasMoreTokens()) {
      try {
        tokenizer = new java.util.StringTokenizer(reader.readLine());
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
    return tokenizer.nextToken();
  }

  private static double nd() {
    return Double.parseDouble(next());
  }

  private static long nl() {
    return Long.parseLong(next());
  }

  private static int[] na(int n) {
    int[] a = new int[n];
    for (int i = 0; i < n; i++)
      a[i] = ni();
    return a;
  }

  private static char[] ns() {
    return next().toCharArray();
  }

  private static long[] nal(int n) {
    long[] a = new long[n];
    for (int i = 0; i < n; i++)
      a[i] = nl();
    return a;
  }

  private static int[][] ntable(int n, int m) {
    int[][] table = new int[n][m];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        table[i][j] = ni();
      }
    }
    return table;
  }

  private static int[][] nlist(int n, int m) {
    int[][] table = new int[m][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        table[j][i] = ni();
      }
    }
    return table;
  }

  private static int ni() {
    return Integer.parseInt(next());
  }

  private static void tr(Object... o) {
    if (is != System.in)
      System.out.println(java.util.Arrays.deepToString(o));
  }
}


import java.io.*;
import java.util.*;

public	 class template
	{
		private InputStream is;
		private PrintWriter pw;
		static char[][] ch;
		static int  x1,x2,y1,y2,n,m,h,k;
		static long dist[][];
		static boolean boo[][];

		void soln()
		{
			is = System.in;
			pw = new PrintWriter(System.out);
			long s = System.currentTimeMillis();
			solve();
			pw.close();
			pw.flush();
			// tr(System.currentTimeMillis() - s + "ms");
		}

		public static void main(String[] args) throws Exception
		{
			new Thread(null, new Runnable()
			{
				public void run()
				{
					try
					{
						// new CODEFORCES().soln();
					} catch (Exception e)
					{
						System.out.println(e);
					}
				}
			}, "1", 1 << 26).start();
			new template().soln();
		}

		void solve()
		{
			long n = nl(), k = nl();
			if(n==0){
				pw.println(0);
				return;
			}
			long MOD = 1000000007;
			long pow1 = pow(2,k,MOD), pow2 = pow(2,k+1,MOD);
			pw.println(((((n%MOD)*pow2)%MOD) - (pow1-1+MOD)%MOD + 2*MOD)%MOD);
			pw.close();
		}
		long pow(long x, long y, long mod){
			long ans = 1;
			while(y>0){
				if(y%2==0) {
					x *= x;
					x %= mod;
					y/=2;
				}
				else{
					ans *= x;
					ans %= mod;
					y-=1;
				}
			}
			return ans;
		}
		long gcd(long a, long b){
			if(b==0) return a;
			return gcd(b,a%b);
		}
		void printArray(long[] arr) {
			for(long i : arr) pw.print(i +" ");
			pw.println();
		}
	static long min(long x, long y){
		return (x<y)?x:y;
	}
	static class Pair implements Comparable<Pair>{
		long val;
		int  x, y;
		Pair(long v, int a, int b){
			val = v; x = a; y = b;
		}
		public int compareTo(Pair p){
			return Long.compare(this.val,p.val);
		}
	}
	private static class Queue{
		int st = 0;
		int et = 0;
		Pair[] arr;
		public Queue(int len) {
			arr = new Pair[len];
		}
		public boolean isEmpty() {
			return st==et;
		}
		public void add(Pair x) {
			arr[et++] = x;
		}
		public Pair poll() {
			return arr[st++];
		}
		public void clear() {
			st = et = 0;
		}
	}
		/*void bfs(int k) {
			while(!q.isEmpty()) {
				int y = q.poll();
				for(long i : amp[y]) {
					if(!b[i]) {
						D[i][k] = D[y][k]+1;
						q.add(i);
						b[i] = true;
					}
				}
			}
		}
		*/
		/*
		int dfs(int x) {
			b[x] = true;
			//start[x] = time++;
			int ans = 1;
			for(int i : amp[x]) {
				if(!b[i]) {
					ans += dfs(i);
				}
			}
			//end[x] = time;
			if(x!= 0 && ans%2==0 && (N-ans)%2==0) cost++;

			return ans;
		}*/

		/*void buildGraph(int n)
		{
			for (int i = 0; i < n; i++)
			{
				int x1 = ni() - 1, y1 = ni() - 1;
				amp[x1].add(y1);
				amp[y1].add(x1);
			}
		}*/
		public static int[] shuffle(int[] a, Random gen)
		{
			for (int i = 0, n = a.length; i < n; i++)
			{
				int ind = gen.nextInt(n - i) + i;
				int d = a[i];
				a[i] = a[ind];
				a[ind] = d;
			}
			return a;
		}
		// To Get Input
		// Some Buffer Methods
		private byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		private int readByte()
		{
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf)
			{
				ptrbuf = 0;
				try
				{
					lenbuf = is.read(inbuf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		private boolean isSpaceChar(int c)
		{
			return !(c >= 33 && c <= 126);
		}

		private int skip()
		{
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

		private double nd()
		{
			return Double.parseDouble(ns());
		}

		private char nc()
		{
			return (char) skip();
		}

		private String ns()
		{
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b)))
			{ // when nextLine, (isSpaceChar(b) && b != '
										// ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		private char[] ns(int n)
		{
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b)))
			{
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		private char[][] nm(int n, int m)
		{
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = ns(m);
			return map;
		}

		private int[] na(int n)
		{
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = ni();
			return a;
		}

		private int ni()
		{
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-')
			{
				minus = true;
				b = readByte();
			}

			while (true)
			{
				if (b >= '0' && b <= '9')
				{
					num = num * 10 + (b - '0');
				} else
				{
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private long nl()
		{
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-')
			{
				minus = true;
				b = readByte();
			}

			while (true)
			{
				if (b >= '0' && b <= '9')
				{
					num = num * 10 + (b - '0');
				} else
				{
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

		private void tr(Object... o)
		{
			if (!oj)
				System.out.println(Arrays.deepToString(o));
		}
	}


import java.io.*;
import java.util.*;
import java.math.BigInteger;
import java.util.Map.Entry;

import static java.lang.Math.*;

public class C extends PrintWriter {

    final long mod = 1_000_000_007;

    long pow(long n, long p) {
        long r = 1;

        while (p > 0) {
            if (p % 2 == 1) {
                r = (r * n) % mod;
            }
            n = (n * n) % mod;
            p /= 2;
        }

        return r;
    }

    long solve(long n, long k) {

        if (k == 0) {
            return (2 * n) % mod;
        }

        if (n == 0) {
            return 0;
        }

        long m = pow(2, k);

        long a = 2;

        a = (a * n) % mod;
        a = (a * m) % mod;

        long b = (m + mod - 1) % mod;

        return ((a - b + mod) % mod);
    }

    void run() {
        long n = nextLong();
        long k = nextLong();

        println(solve(n, k));
    }

    boolean skip() {
        while (hasNext()) {
            next();
        }
        return true;
    }

    int[][] nextMatrix(int n, int m) {
        int[][] matrix = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                matrix[i][j] = nextInt();
        return matrix;
    }

    String next() {
        while (!tokenizer.hasMoreTokens())
            tokenizer = new StringTokenizer(nextLine());
        return tokenizer.nextToken();
    }

    boolean hasNext() {
        while (!tokenizer.hasMoreTokens()) {
            String line = nextLine();
            if (line == null) {
                return false;
            }
            tokenizer = new StringTokenizer(line);
        }
        return true;
    }

    int[] nextArray(int n) {
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = nextInt();
        }
        return array;
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException err) {
            return null;
        }
    }

    public C(OutputStream outputStream) {
        super(outputStream);
    }

    static BufferedReader reader;
    static StringTokenizer tokenizer = new StringTokenizer("");
    static Random rnd = new Random();
    static boolean OJ;

    public static void main(String[] args) throws IOException {
        OJ = System.getProperty("ONLINE_JUDGE") != null;
        C solution = new C(System.out);
        if (OJ) {
            reader = new BufferedReader(new InputStreamReader(System.in));
            solution.run();
        } else {
            reader = new BufferedReader(new FileReader(new File(C.class.getName() + ".txt")));
            long timeout = System.currentTimeMillis();
            while (solution.hasNext()) {
                solution.run();
                solution.println();
                solution.println("----------------------------------");
            }
            solution.println("time: " + (System.currentTimeMillis() - timeout));
        }
        solution.close();
        reader.close();
    }
}


import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.StringTokenizer;
public class Main{
    public long power(long x, long y, long p)
    {

        long res = 1;

        while (y > 0)
        {
            if((y & 1)==1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    public static void main(String[] args) throws IOException{
        // TODO Auto-generated method stub
        Scanner sc=new Scanner(System.in);
        Main mm=new Main();
        long x=sc.nextLong();
            long k=sc.nextLong();
            if(x==0) {
                System.out.println(0);
            }
            else {
            long temp=mm.power(2, k, 1000000007);
            long temp1=(2*x-1)%(1000000007);
            long temp3=(temp1*temp)%(1000000007);
            System.out.println((temp3+1)%1000000007);
            }
    }
 }

class trienode{
    trienode[] next=new trienode[26];
    int count;
    char value;
    boolean last;
    trienode() {
        this.value='0';
        this.count=0;
    }
    trienode(char x) {
        this.value=x;
        this.count=1;
    }

}
class trie{
    trienode root=new trienode();
    public void insert(String s) {
        trienode temp=root;
        int length=s.length();
        for(int i=0;i<length;i++) {
            char c=s.charAt(i);
            int index=c-'a';
            if(temp.next[index]==null) {
                temp.next[index]=new trienode(c);
            }
            else {
                temp.next[index].count++;
            }
            if(i==length-1) {
                temp.next[index].last=true;
            }
            temp=temp.next[index];

        }

    }
    public String find(String s) {
        trienode temp=root;
        String ans="";
        int pos=0;
        char c=s.charAt(pos);
        int index=c-'a';
        while(temp.next[index]!=null) {
            temp=temp.next[index];
            ans+=temp.value;
            if(pos==s.length()-1) {
                break;
            }
            c=s.charAt(++pos);
            index=c-'a';

        }
        while(temp.last!=true) {
            int position=-1;
            for(int i=0;i<26;i++) {
            if(temp.next[i]!=null) {
                ans+=temp.next[i].value;
                position=i+0;
                break;
            }

        }
            temp=temp.next[position];
        }
        return ans;
    }
}
class node{
    int index;
    int a;
    int b;
    node(int index,int a,int b){
        this.a=a;
        this.b=b;this.index=index;

    }
}
class comp implements Comparator<node>{
    public int compare(node n1,node n2) {
        if(n1.b>n2.b) {
            return 1;
        }
        else if(n1.b<n2.b) {
            return -1;
        }
        else {
            return 0;
        }
    }
}
class cc implements Comparator<node>{
    public int compare(node n1,node n2) {
        if(n1.index>n2.index) {
            return 1;
        }
        else if(n1.index<n2.index) {
            return -1;
        }
        else {
            return 0;
        }
    }
}

/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        }
        return tokenizer.nextToken();
    }

    static int nextInt() throws IOException {
        return Integer.parseInt( next() );
    }

    static double nextDouble() throws IOException {
        return Double.parseDouble( next() );
    }
}


import java.util.*;
import java.io.*;

public class virtual1{

    static InputReader in = new InputReader();
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
            long x = in.nextLong();
            long k = in.nextLong();
            long mod = (long)1e9+7l;
            //out.println(mod);
            long mul1 = 1;
            long mul2 = 2*x-1;
            mul2 = mul2%mod;
            long pow = k;
            long to = 2;
            while(pow>0l){
                if(pow%2l==1l){
                    mul1 = mul1*to;
                    mul1%=mod;
                }
                to=to*to;
                to%=mod;
                pow = pow/2l;
            }
            mul1 = mul1*mul2;
            mul1%=mod;
            mul1+=1;
            if(x!=0)
            out.println(mul1%mod);
            else
            out.println(0);

        out.close();
    }

    static class InputReader
    {
        BufferedReader br;
        StringTokenizer st;

        public InputReader()
        {
            br = new BufferedReader(new
                     InputStreamReader(System.in));
        }

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
public class algo93
{
    public static void main(String args[])
    {
        Scanner ex=new Scanner(System.in);
        long x=ex.nextLong();
        long k=ex.nextLong();
        long mod=1000000007;
        if(k==0)
        System.out.println((2*x)%mod);
        else if(x==0)
        System.out.println("0");
        else
        {
            long pow=power(2,k);
            long pow1=(2*pow)%mod;
            long ans=(pow1*(x%mod))-pow+1;
            if(ans<0)
            ans=ans+mod;
            ans=ans%mod;
            System.out.println(ans);
        }
    }
    public static long power(long x,long y)
    {
        if (y == 0)
        return 1;
        long mod=1000000007;
        long pow=power(x,y/2);
        pow=(pow*pow)%mod;
        if(y%2==0)
        return pow;
        else
        return ((x%mod)*pow)%mod;
    }
}


import java.io.*;
import java.util.StringTokenizer;

public class Test {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 1024 * 48);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String str = br.readLine();
        StringTokenizer st = new StringTokenizer(str, " ");
        long x = Long.parseLong(st.nextToken());
        long k = Long.parseLong(st.nextToken());
        if (x == 0) {
            bw.write(0 + "\n");
        } else {
            int power = power(k, 1000000007);
            long answer = (((power * 2) % 1000000007) * (x % 1000000007)) % 1000000007;
            answer -= power - 1;
            answer = (answer + 1000000007) % 1000000007;
            bw.write(answer + "\n");
        }
        bw.flush();
    }

    public static int power(long a, int m) {
        if (a == 0) {
            return 1;
        }
        long pow = power(a / 2, m);
        if (a % 2 == 1) {
            return (int)(((pow * pow) % m) * 2) % m;
        } else {
            return (int)((pow * pow) % m);
        }
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;

public class Main
{
	static long MOD=1000000007;
	public static long pow(long x,long k){
		long base=x%MOD;
		long res=1;
		while(k>0){
			if((k&1)==1){
				res=(res*base)%MOD;
			}
			base=(base*base)%MOD;
			k>>=1;
		}
		return res;
	}

	public static void main (String[] args) throws java.lang.Exception
	{
		Scanner scan=new Scanner(System.in);
		long x=scan.nextLong();
		long k=scan.nextLong();
		long MOD=1000000007;
		if(x==0){System.out.println(0);return;}
		x %= MOD;
		long a=pow(2L,k+1);
		long b=pow(2L,k);
		long res=(a*x)%MOD-b+1;
		if(res<0){res+=MOD;}
		System.out.println(res%MOD);
	}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 * @author pttrung
 */
public class B_Round_371_Div1 {

    public static long MOD = 1000000007;
    static int c = 0;

    public static void main(String[] args) throws FileNotFoundException {
        // PrintWriter out = new PrintWriter(new FileOutputStream(new File(
        // "output.txt")));

        Scanner in = new Scanner();
        int n = in.nextInt();
        int minX = -1;
        int start = 1;
        int end = n;
        c = 0;
        while (start <= end) {
            int mid = (start + end) >> 1;
            c = increaseC(c);
            System.out.println("? " + mid + " 1 " + n + " " + n);
            System.out.flush();

            int v = in.nextInt();
            if (v == 2) {
                minX = mid;
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        //System.out.println("Minx " + minX);
        int maxX = -1;
        start = minX;
        end = n;
        while (start <= end) {
            int mid = (start + end) >> 1;
            c = increaseC(c);
            System.out.println("? " + minX + " 1 " + mid + " " + n);
            System.out.flush();
            int v = in.nextInt();
            if (v == 2) {
                maxX = mid;
                end = mid - 1;
            } else {
                start = mid + 1;
            }
        }
        // System.out.println("Maxx " + maxX);
        int minY = -1;
        start = 1;
        end = n;
        while (start <= end) {
            int mid = (start + end) >> 1;
            c = increaseC(c);
            System.out.println("? " + minX + " " + mid + " " + maxX + " " + n);
            System.out.flush();

            int v = in.nextInt();
            if (v == 2) {
                minY = mid;
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        // System.out.println("MinY " + minY);
        int maxY = -1;
        start = minY;
        end = n;
        while (start <= end) {
            int mid = (start + end) >> 1;
            c = increaseC(c);
            System.out.println("? " + minX + " " + minY + " " + maxX + " " + mid);
            System.out.flush();

            int v = in.nextInt();
            if (v == 2) {
                maxY = mid;
                end = mid - 1;
            } else {
                start = mid + 1;
            }
        }
        // System.out.println("MaxY " + maxY);
        int middleMinX = maxX;
        start = minX;
        end = maxX;
        while (start <= end) {
            int mid = (start + end) >> 1;
            c = increaseC(c);
            System.out.println("? " + minX + " " + minY + " " + mid + " " + maxY);
            System.out.flush();

            int v = in.nextInt();
            if (v == 1) {
                middleMinX = mid;
                end = mid - 1;
            } else {
                start = mid + 1;
            }
        }
        //System.out.println("MiddleMinX " + middleMinX);
        int middleMaxX = -1;
        start = middleMinX + 1;
        end = maxX;
        while (start <= end) {
            int mid = (start + end) >> 1;
            c = increaseC(c);
            System.out.println("? " + mid + " " + minY + " " + maxX + " " + maxY);
            System.out.flush();

            int v = in.nextInt();
            if (v == 1) {
                middleMaxX = mid;
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }

        // System.out.println("MiddleMaxX " + middleMaxX);
        if (middleMaxX == -1) {
            int middleMinY = -1;
            start = minY;
            end = maxY;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + minY + " " + maxX + " " + mid);
                System.out.flush();

                int v = in.nextInt();
                if (v == 1) {
                    middleMinY = mid;
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            }
            //System.out.println("MiddleMinY " + middleMinY);
            int middleMaxY = -1;
            start = middleMinY + 1;
            end = maxY;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + mid + " " + maxX + " " + maxY);
                System.out.flush();

                int v = in.nextInt();
                if (v == 1) {
                    middleMaxY = mid;
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
            //System.out.println("MiddleMaxY " + middleMaxY);
            if (minX == maxX) {
                System.out.println("! " + minX + " " + minY + " " + maxX + " " + middleMinY + " " + minX + " " + middleMaxY + " " + maxX + " " + maxY);
                System.out.flush();
            } else {
                int[] a = calX(minX, maxX, minY, middleMinY, in);
                int[] b = calX(minX, maxX, middleMaxY, maxY, in);
                check(a);
                check(b);
                System.out.println("! " + a[0] + " " + minY + " " + a[1] + " " + middleMinY + " " + b[0] + " " + middleMaxY + " " + b[1] + " " + maxY);
                System.out.flush();
            }
        } else if (minY == maxY) {
            System.out.println("! " + minX + " " + minY + " " + middleMinX + " " + maxY + " " + middleMaxX + " " + minY + " " + maxX + " " + maxY);
            System.out.flush();
        } else {
            int[] a = calY(minX, middleMinX, minY, maxY, in);
            int[] b = calY(middleMaxX, maxX, minY, maxY, in);
            check(a);
            check(b);
            System.out.println("! " + minX + " " + a[0] + " " + middleMinX + " " + a[1] + " " + middleMaxX + " " + b[0] + " " + maxX + " " + b[1]);
            System.out.flush();
        }

    }

    static void check(int[] v) {
        if (v[0] == -1 || v[1] == -1) {
            throw new NullPointerException();
        }
    }

    static int increaseC(int c) {
        if (c == 200) {
            throw new NullPointerException();
        }
        return c + 1;
    }

    public static int[] calY(int minX, int maxX, int minY, int maxY, Scanner in) {
        c = increaseC(c);
        System.out.println("? " + minX + " " + minY + " " + maxX + " " + (maxY - 1));
        System.out.flush();
        int v = in.nextInt();
        c = increaseC(c);
        System.out.println("? " + minX + " " + (minY + 1) + " " + maxX + " " + maxY);
        System.out.flush();
        int o = in.nextInt();
        if (v == 1 && o == 1) {
            int a = -1;
            int start = minY;
            int end = maxY;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + minY + " " + maxX + " " + mid);
                System.out.flush();
                if (in.nextInt() == 1) {
                    a = mid;
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            }
            int b = -1;
            start = minY;
            end = a;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + mid + " " + maxX + " " + a);
                System.out.flush();
                if (in.nextInt() == 1) {
                    b = mid;
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
            return new int[]{b, a};
        } else if (v == 1) {
            int a = -1;
            int start = minY;
            int end = maxY;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + minY + " " + maxX + " " + mid);
                System.out.flush();
                if (in.nextInt() == 1) {
                    a = mid;
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            }
            return new int[]{minY, a};
        } else if (o == 1) {
            int b = -1;
            int start = minY;
            int end = maxY;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + mid + " " + maxX + " " + maxY);
                System.out.flush();
                if (in.nextInt() == 1) {
                    b = mid;
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
            return new int[]{b, maxY};
        } else {
            return new int[]{minY, maxY};
        }
    }

    public static int[] calX(int minX, int maxX, int minY, int maxY, Scanner in) {
        c = increaseC(c);
        System.out.println("? " + minX + " " + minY + " " + (maxX - 1) + " " + maxY);
        System.out.flush();
        int v = in.nextInt();
        c = increaseC(c);
        System.out.println("? " + (minX + 1) + " " + minY + " " + maxX + " " + maxY);
        System.out.flush();
        int o = in.nextInt();
        if (v == 1 && o == 1) {
            int a = -1;
            int start = minX;
            int end = maxX;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + minY + " " + mid + " " + maxY);
                System.out.flush();
                if (in.nextInt() == 1) {
                    a = mid;
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            }
            int b = -1;
            start = minX;
            end = a;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + mid + " " + minY + " " + a + " " + maxY);
                System.out.flush();
                if (in.nextInt() == 1) {
                    b = mid;
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
            return new int[]{b, a};
        } else if (v == 1) {
            int a = -1;
            int start = minX;
            int end = maxX;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + minX + " " + minY + " " + mid + " " + maxY);
                System.out.flush();
                if (in.nextInt() == 1) {
                    a = mid;
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            }
            return new int[]{minX, a};
        } else if (o == 1) {
            int b = -1;
            int start = minX;
            int end = maxX;
            while (start <= end) {
                int mid = (start + end) >> 1;
                c = increaseC(c);
                System.out.println("? " + mid + " " + minY + " " + maxX + " " + maxY);
                System.out.flush();
                if (in.nextInt() == 1) {
                    b = mid;
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
            return new int[]{b, maxX};
        } else {
            return new int[]{minX, maxX};
        }
    }

    public static int[] KMP(String val) {
        int i = 0;
        int j = -1;
        int[] result = new int[val.length() + 1];
        result[0] = -1;
        while (i < val.length()) {
            while (j >= 0 && val.charAt(j) != val.charAt(i)) {
                j = result[j];
            }
            j++;
            i++;
            result[i] = j;
        }
        return result;

    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;

    }

    public static class Point implements Comparable<Point> {

        int x, y;

        public Point(int start, int end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 47 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {
            return Integer.compare(x, o.x);
        }
    }

    public static class FT {

        long[] data;

        FT(int n) {
            data = new long[n];
        }

        public void update(int index, long value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public long get(int index) {
            long result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

    public static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static long pow(long a, long b, long MOD) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2, MOD);
        if (b % 2 == 0) {
            return val * val % MOD;
        } else {
            return val * (val * a % MOD) % MOD;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //  br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.HashMap;
import java.io.IOException;
import java.util.ArrayList;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author ilyakor
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskB solver = new TaskB();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskB {
        ArrayList<PointInt[]> al;
        TaskB.Interactor interactor;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.nextInt();
            //for (int itt = 0; itt < 100; ++itt) {
            interactor = new TaskB.IOInteractor(new Scanner(in.getStream()), out.getWriter());//new TestInteractor(n);
            Assert.assertTrue(interactor.query(1, 1, n, n) == 2);
            int lx = 1, rx = n, ly = 1, ry = n;
            for (int it = 0; it < 20; ++it) {
                int tx = (lx + rx) / 2;
                if (interactor.query(1, 1, tx, n) >= 1)
                    rx = tx;
                else
                    lx = tx;
                int ty = (ly + ry) / 2;
                if (interactor.query(1, 1, n, ty) >= 1)
                    ry = ty;
                else
                    ly = ty;
            }
            al = new ArrayList<>();
            if (interactor.query(1, 1, lx, n) == 1 && interactor.query(lx + 1, 1, n, n) == 1) {
                dfs(1, 1, lx, n);
                dfs(lx + 1, 1, n, n);
            } else if (interactor.query(1, 1, rx, n) == 1 && interactor.query(rx + 1, 1, n, n) == 1) {
                dfs(1, 1, rx, n);
                dfs(rx + 1, 1, n, n);
            } else if (interactor.query(1, 1, n, ly) == 1 && interactor.query(1, ly + 1, n, n) == 1) {
                dfs(1, 1, n, ly);
                dfs(1, ly + 1, n, n);
            } else if (interactor.query(1, 1, n, ry) == 1 && interactor.query(1, ry + 1, n, n) == 1) {
                dfs(1, 1, n, ry);
                dfs(1, ry + 1, n, n);
            } else {
                throw new RuntimeException("WTF");
            }
            Assert.assertTrue(al.size() == 2);
            interactor.answer(al.get(0)[0].x, al.get(0)[0].y, al.get(0)[1].x, al.get(0)[1].y, al.get(1)[0].x, al.get(1)[0].y, al.get(1)[1].x, al.get(1)[1].y);
            //}
        }

        private void dfs(int x1, int y1, int x2, int y2) {
            int t;
            t = x1;
            for (int i = 0; i < 20; ++i) {
                int x = (t + x2) / 2;
                if (interactor.query(x1, y1, x, y2) == 1)
                    x2 = x;
                else
                    t = x;
            }
            if (interactor.query(x1, y1, t, y2) == 1)
                x2 = t;
            t = x2;
            for (int i = 0; i < 20; ++i) {
                int x = (t + x1) / 2;
                if (interactor.query(x, y1, x2, y2) == 1)
                    x1 = x;
                else
                    t = x;
            }
            if (interactor.query(t, y1, x2, y2) == 1)
                x1 = t;
            t = y1;
            for (int i = 0; i < 20; ++i) {
                int y = (t + y2) / 2;
                if (interactor.query(x1, y1, x2, y) == 1)
                    y2 = y;
                else
                    t = y;
            }
            if (interactor.query(x1, y1, x2, t) == 1)
                y2 = t;
            t = y2;
            for (int i = 0; i < 20; ++i) {
                int y = (t + y1) / 2;
                if (interactor.query(x1, y, x2, y2) == 1)
                    y1 = y;
                else
                    t = y;
            }
            if (interactor.query(x1, t, x2, y2) == 1)
                y1 = t;

            al.add(new PointInt[]{new PointInt(x1, y1), new PointInt(x2, y2)});
        }

        interface Interactor {
            int query(int x1, int y1, int x2, int y2);

            void answer(int x11, int y11, int x12, int y12,
                        int x21, int y21, int x22, int y22);

        }

        static class Query {
            int x1;
            int y1;
            int x2;
            int y2;

            public Query(int x1, int y1, int x2, int y2) {
                this.x1 = x1;
                this.y1 = y1;
                this.x2 = x2;
                this.y2 = y2;
            }

            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;

                TaskB.Query query = (TaskB.Query) o;

                if (x1 != query.x1) return false;
                if (y1 != query.y1) return false;
                if (x2 != query.x2) return false;
                return y2 == query.y2;

            }

            public int hashCode() {
                int result = x1;
                result = 31 * result + y1;
                result = 31 * result + x2;
                result = 31 * result + y2;
                return result;
            }

        }

        static class IOInteractor implements TaskB.Interactor {
            Scanner in;
            PrintWriter out;
            HashMap<TaskB.Query, Integer> cache;

            public IOInteractor(Scanner in, PrintWriter out) {
                this.in = in;
                this.out = out;
                cache = new HashMap<>();
            }

            public int query(int x1, int y1, int x2, int y2) {
                TaskB.Query q = new TaskB.Query(x1, y1, x2, y2);
                if (cache.containsKey(q))
                    return cache.get(q);
                if (x1 > x2 || y1 > y2)
                    return 0;
                Assert.assertTrue(x1 >= 1 && y1 >= 1);
                out.println("? " + x1 + " " + y1 + " " + x2 + " " + y2);
                out.flush();
                int res = in.nextInt();
                cache.put(q, res);
                return res;
            }

            public void answer(int x11, int y11, int x12, int y12, int x21, int y21, int x22, int y22) {
                out.println("! " + x11 + " " + y11 + " " + x12 + " " + y12 + " " + x21 + " " + y21 + " " + x22 + " " + y22);
                out.flush();
            }

        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buffer = new byte[10000];
        private int cur;
        private int count;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public static boolean isSpace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public int read() {
            if (count == -1) {
                throw new InputMismatchException();
            }
            try {
                if (cur >= count) {
                    cur = 0;
                    count = stream.read(buffer);
                    if (count <= 0)
                        return -1;
                }
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            return buffer[cur++];
        }

        public int readSkipSpace() {
            int c;
            do {
                c = read();
            } while (isSpace(c));
            return c;
        }

        public int nextInt() {
            int sgn = 1;
            int c = readSkipSpace();
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res = res * 10 + c - '0';
                c = read();
            } while (!isSpace(c));
            res *= sgn;
            return res;
        }

        public InputStream getStream() {
            return stream;
        }

    }

    static class PointInt {
        public int x;
        public int y;

        public PointInt(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public PointInt() {
            x = 0;
            y = 0;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public PrintWriter getWriter() {
            return writer;
        }

        public void close() {
            writer.close();
        }

    }

    static class Assert {
        public static void assertTrue(boolean flag) {
//        if (!flag)
//        while (true);
            if (!flag)
                throw new AssertionError();
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            BSearchingRectangles solver = new BSearchingRectangles();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class BSearchingRectangles {
        FastInput in;
        FastOutput out;
        int n;

        public void solve(int testNumber, FastInput in, FastOutput out) {
            this.in = in;
            this.out = out;
            n = in.readInt();

            IntBinarySearch upDown = new IntBinarySearch() {

                public boolean check(int mid) {
                    return query(1, n, 1, mid) >= 1;
                }
            };

            IntBinarySearch leftRight = new IntBinarySearch() {

                public boolean check(int mid) {
                    return query(1, mid, 1, n) >= 1;
                }
            };
            int threshold = upDown.binarySearch(1, n);
            int[] r1;
            int[] r2;
            if (query(1, n, 1, threshold) == 1 &&
                    query(1, n, threshold + 1, n) == 1) {
                r1 = find(1, n, 1, threshold);
                r2 = find(1, n, threshold + 1, n);
            } else {
                threshold = leftRight.binarySearch(1, n);
                r1 = find(1, threshold, 1, n);
                r2 = find(threshold + 1, n, 1, n);
            }

            out.append("! ");
            output(r1);
            output(r2);
            out.flush();
        }

        public void output(int[] ans) {
            for (int x : ans) {
                out.append(x).append(' ');
            }
        }

        public int[] find(int l, int r, int d, int u) {
            IntBinarySearch downIBS = new IntBinarySearch() {

                public boolean check(int mid) {
                    return query(l, r, mid, u) == 0;
                }
            };
            int y1 = downIBS.binarySearch(d, u);
            if (query(l, r, y1, u) == 0) {
                y1--;
            }

            IntBinarySearch upIBS = new IntBinarySearch() {

                public boolean check(int mid) {
                    return query(l, r, d, mid) >= 1;
                }
            };
            int y2 = upIBS.binarySearch(d, u);

            IntBinarySearch leftIBS = new IntBinarySearch() {

                public boolean check(int mid) {
                    return query(mid, r, d, u) == 0;
                }
            };
            int x1 = leftIBS.binarySearch(l, r);
            if (query(x1, r, d, u) == 0) {
                x1--;
            }

            IntBinarySearch rightIBS = new IntBinarySearch() {

                public boolean check(int mid) {
                    return query(l, mid, d, u) >= 1;
                }
            };
            int x2 = rightIBS.binarySearch(l, r);

            return new int[]{x1, y1, x2, y2};
        }

        public int query(int l, int r, int d, int u) {
            if (l > r || d > u) {
                return 0;
            }
            out.printf("? %d %d %d %d", l, d, r, u).println().flush();
            return in.readInt();
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static int floorAverage(int x, int y) {
            return (x & y) + ((x ^ y) >> 1);
        }

    }

    static abstract class IntBinarySearch {
        public abstract boolean check(int mid);

        public int binarySearch(int l, int r) {
            if (l > r) {
                throw new IllegalArgumentException();
            }
            while (l < r) {
                int mid = DigitUtils.floorAverage(l, r);
                if (check(mid)) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            return l;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(String c) {
            cache.append(c);
            return this;
        }

        public FastOutput printf(String format, Object... args) {
            cache.append(String.format(format, args));
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }
}


import java.io.*;
import java.util.*;
import java.math.*;

public class B {
	public static void main(String[] args) throws IOException {

		/**/
		Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
		/*/
		Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(new FileInputStream("src/b.in"))));
		/**/

		int n = sc.nextInt();
		int l1 = 1;
		int r1 = n;
		int b1 = 1;
		int t1 = n;
		int min = b1;
		int max = t1;
		while (min != max) {
			int mid = (min+max)/2;
			System.out.println("? "+l1+" "+b1+" "+r1+" "+mid);
			System.out.flush();
			if (sc.nextInt() >= 1)
				max = mid;
			else
				min = mid+1;
		}
		t1 = min;
		min = l1;
		max = r1;
		while (min != max) {
			int mid = (min+max)/2;
			System.out.println("? "+l1+" "+b1+" "+mid+" "+t1);
			System.out.flush();
			if (sc.nextInt() >= 1)
				max = mid;
			else
				min = mid+1;
		}
		r1 = min;
		min = b1;
		max = t1;
		while (min != max) {
			int mid = (min+max+1)/2;
			System.out.println("? "+l1+" "+mid+" "+r1+" "+t1);
			System.out.flush();
			if (sc.nextInt() >= 1)
				min = mid;
			else
				max = mid-1;
		}
		b1 = min;
		min = l1;
		max = r1;
		while (min != max) {
			int mid = (min+max+1)/2;
			System.out.println("? "+mid+" "+b1+" "+r1+" "+t1);
			System.out.flush();
			if (sc.nextInt() >= 1)
				min = mid;
			else
				max = mid-1;
		}
		l1 = min;
		int l2 = 1;
		int r2 = n;
		int b2 = 1;
		int t2 = n;
		min = b2;
		max = t2;
		while (min != max) {
			int mid = (min+max+1)/2;
			System.out.println("? "+l2+" "+mid+" "+r2+" "+t2);
			System.out.flush();
			if (sc.nextInt() >= 1)
				min = mid;
			else
				max = mid-1;
		}
		b2 = min;
		min = l2;
		max = r2;
		while (min != max) {
			int mid = (min+max+1)/2;
			System.out.println("? "+mid+" "+b2+" "+r2+" "+t2);
			System.out.flush();
			if (sc.nextInt() >= 1)
				min = mid;
			else
				max = mid-1;
		}
		l2 = min;
		min = b2;
		max = t2;
		while (min != max) {
			int mid = (min+max)/2;
			System.out.println("? "+l2+" "+b2+" "+r2+" "+mid);
			System.out.flush();
			if (sc.nextInt() >= 1)
				max = mid;
			else
				min = mid+1;
		}
		t2 = min;
		min = l2;
		max = r2;
		while (min != max) {
			int mid = (min+max)/2;
			System.out.println("? "+l2+" "+b2+" "+mid+" "+t2);
			System.out.flush();
			if (sc.nextInt() >= 1)
				max = mid;
			else
				min = mid+1;
		}
		r2 = min;
		System.out.println("! "+l1+" "+b1+" "+r1+" "+t1+" "+l2+" "+b2+" "+r2+" "+t2);
		System.out.flush();
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    private static StringTokenizer st;
    private static BufferedReader br;
    public static long MOD = 1000000007;

    public static void print(Object x) {
        System.out.println(x + "");
    }
    public static String join(Collection<?> x, String space) {
        if (x.size() == 0) return "";
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Object elt : x) {
            if (first) first = false;
            else sb.append(space);
            sb.append(elt);
        }
        return sb.toString();
    }

    public static String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            String line = br.readLine();
            st = new StringTokenizer(line.trim());
        }
        return st.nextToken();
    }
    public static int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }
    public static long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    // Finds smallest rectangle containing something along 1 dimension.
    public static long[] search(long[] none, long[] some) throws IOException {
        long[] med = new long[4];
        for (int i = 0; i < 4; i++) {
            if (Math.abs(none[i] - some[i]) == 1) {
                return some;
            }
            med[i] = (none[i] + some[i]) / 2;
        }

        int ans = query(med);

        if (ans > 0) return search(none, med);
        else return search(med, some);
    }

    public static int query(long[] query) throws IOException {
        print("? " + arr(query));
        System.out.flush();

        int ans = nextInt();
        if (contains(query)) ans -= 1;

        return ans;
    }

    public static boolean contains(long[] search) {
        if (rect1 == null) return false;
        if (search[0] > rect1[0]) return false;
        if (search[1] > rect1[1]) return false;
        if (search[2] < rect1[2]) return false;
        if (search[3] < rect1[3]) return false;
        return true;
    }

    public static String arr(long[] x) {
        return x[0] + " " + x[1] + " " + x[2] + " " + x[3];
    }
    public static long[] find() throws IOException {
        long[] d0 = {1, 1, 1, 1};
        long[] some = {1, 1, n, n};
        if (query(d0) > 0) {
            return d0;
        }
//        print("   " + arr(some));
        long[] none = {1, 1, n, 1};
        if (query(none) > 0) some = none;
        else some = search(none, some);

//        print("   " + arr(some));
        none = new long[] {1, 1, 1, some[3]};
        if (query(none) > 0) some = none;
        else some = search(none, some);

//        print("   " + arr(some));
        none = new long[] {1, some[3], some[2], some[3]};
        if (query(none) > 0) some = none;
        else some = search(none, some);

//        print("   " + arr(some));
        none = new long[] {some[2], some[1], some[2], some[3]};
        if (query(none) > 0) some = none;
        else some = search(none, some);
        return some;
    }

    public static long[] rect1 = null;
    public static long[] rect2 = null;
    public static long n;

    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));

        n = nextLong();

        rect1 = find();
        rect2 = find();
        print("! " + arr(rect1) + " "
                   + arr(rect2));
        System.out.flush();
    }
}


import java.io.*;
import java.util.Locale;
import java.util.StringTokenizer;

public class B implements Runnable {

    private static final boolean ONLINE_JUDGE = true;//System.getProperty("ONLINE_JUDGE") != null;

    private BufferedReader in;
    private PrintWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    private void init() throws FileNotFoundException {
        Locale.setDefault(Locale.US);
        String fileName = "";
        if (ONLINE_JUDGE && fileName.isEmpty()) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            if (fileName.isEmpty()) {
                in = new BufferedReader(new FileReader("input.txt"));
                out = new PrintWriter("output.txt");
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new PrintWriter(fileName + ".out");
            }
        }
    }

    String readString() {
        while (!tok.hasMoreTokens()) {
            try {
                tok = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                return null;
            }
        }
        return tok.nextToken();
    }

    int readInt() {
        return Integer.parseInt(readString());
    }

    long readLong() {
        return Long.parseLong(readString());
    }

    double readDouble() {
        return Double.parseDouble(readString());
    }

    int[] readIntArray(int size) {
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = readInt();
        }
        return a;
    }

    public static void main(String[] args) {
        //new Thread(null, new _Solution(), "", 128 * (1L << 20)).start();
        new B().run();
    }

    long timeBegin, timeEnd;

    void time() {
        timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    @Override
    public void run() {
        try {
            timeBegin = System.currentTimeMillis();
            init();
            int n = readInt();
            int[] rect1 = solve1(n);
            int[] rect2 = solve2(n, rect1);

            out.printf("! %s %s %s %s %s %s %s %s\n", rect1[0], rect1[1], rect1[2], rect1[3],
                    rect2[0], rect2[1], rect2[2], rect2[3]);
            out.flush();
            out.close();
            time();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    int ask(int x1, int y1, int x2, int y2) {
        out.println("? " + x1 + " " + y1 + " " + x2 + " " + y2);
        out.flush();
        return readInt();
    }

    int ask(int x1, int y1, int x2, int y2, int[] rect) {
        out.println("? " + x1 + " " + y1 + " " + x2 + " " + y2);
        out.flush();
        int res = readInt();
        if (rect[0] >= x1 && rect[2] <= x2 && rect[1] >= y1 && rect[3] <= y2) {
            res--;
        }
        return res;
    }

    int[] dropTopAndLeft1(int x2, int y2) {
        int x1 = x2, y1 = y2;
        int left = 1, right = x2;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(mid, 1, x2, y2);
            if (count >= 1) {
                x1 = mid;
                left = mid + 1;
            }
            if (count == 0) {
                right = mid - 1;
            }
        }
        left = 1;
        right = y2;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(x1, mid, x2, y2);
            if (count >= 1) {
                y1 = mid;
                left = mid + 1;
            }
            if (count == 0) {
                right = mid - 1;
            }
        }
        return new int[]{x1, y1, x2, y2};
    }

    private int[] solve1(int n) {

        int x = -1;
        int left = 1, right = n;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(1, 1, mid, n);
            if (count >= 1) {
                x = mid;
                right = mid - 1;
            }
            if (count == 0) {
                left = mid + 1;
            }
        }

        left = 1;
        right = n;
        int y = -1;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(1, 1, x, mid);
            if (count >= 1) {
                y = mid;
                right = mid - 1;
            }
            if (count == 0) {
                left = mid + 1;
            }
        }

        return dropTopAndLeft1(x, y);
    }

    private int[] solve2(int n, int[] rect) {

        int x = -1;
        int left = 1, right = n;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(mid, 1, n, n, rect);
            if (count >= 1) {
                x = mid;
                left = mid + 1;
            }
            if (count == 0) {
                right = mid - 1;
            }
        }

        left = 1;
        right = n;
        int y = -1;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(x, mid, n, n, rect);
            if (count >= 1) {
                y = mid;
                left = mid + 1;
            }
            if (count == 0) {
                right = mid - 1;
            }
        }

        return dropTopAndLeft2(x, y, n, rect);
    }

    int[] dropTopAndLeft2(int x1, int y1, int n, int[] rect) {
        int x2 = x1, y2 = y1;
        int left = x1, right = n;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(x1, y1, mid, n, rect);
            if (count >= 1) {
                x2 = mid;
                right = mid - 1;
            }
            if (count == 0) {
                left = mid + 1;
            }
        }
        left = y1;
        right = n;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int count = ask(x1, y1, x2, mid, rect);
            if (count == 1) {
                y2 = mid;
                right = mid - 1;
            }
            if (count == 0) {
                left = mid + 1;
            }
        }
        return new int[]{x1, y1, x2, y2};
    }
}