using System; using System.IO; using System.Collections.Generic; using System.Linq; namespace No403 { public class Program { void Solve(StreamScanner ss, StreamWriter sw) { //--------------------------------- var S = ss.Next(String).Split('^').Select(long.Parse).ToArray(); var A = (ModInt)S[0]; var B = S[1]; var C = S[2]; if (A.Value == 0) { sw.WriteLine($"{0} {0}"); return; } var ans1 = A.Pow(B).Pow(C); var ans2 = A.Pow(new ModInt(B, 1000000006).Pow(C).Value); sw.WriteLine($"{ans1} {ans2}"); //--------------------------------- } static void Main() { var ss = new StreamScanner(new StreamReader(Console.OpenStandardInput())); var sw = new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false}; new Program().Solve(ss, sw); sw.Flush(); } static readonly Func String = s => s; } public struct ModInt { public static int DefaultMod = 1000000007; readonly long value; readonly int mod; public int Value { get { return (int)value; } } public int Mod { get { return mod; } } public ModInt Inverse { get { return GetInverse(); } } public ModInt(long value) : this(value, DefaultMod) { } public ModInt(long value, int mod) { value %= mod; this.value = value < 0 ? value + mod : value; this.mod = mod; } ModInt GetInverse() { if (value == 0) throw new InvalidOperationException("value must NOT equal 0"); return Pow(Mod - 2); } public ModInt Square() { return this * this; } public ModInt Pow(long exp) { if (exp == 0) return new ModInt(1, mod); if (exp % 2 == 0) return Pow(exp / 2).Square(); return this * Pow(exp - 1); } public static ModInt Parse(string str) { return long.Parse(str); } public static ModInt Parse(string str, int mod) { return new ModInt(long.Parse(str), mod); } public static implicit operator ModInt(long value) { return new ModInt(value); } static void AssertSameMod(ModInt left, ModInt right) { if (left.mod != right.mod) throw new ArgumentException($"{nameof(left.Mod)} != {nameof(right.Mod)}"); } public static ModInt operator +(ModInt left, ModInt right) { AssertSameMod(left, right); return new ModInt(left.value + right.value, left.mod); } public static ModInt operator +(ModInt mi, long num) { return mi + new ModInt(num, mi.mod); } public static ModInt operator -(ModInt left, ModInt right) { AssertSameMod(left, right); return new ModInt(left.value - right.value, left.mod); } public static ModInt operator -(ModInt mi, long num) { return mi - new ModInt(num, mi.mod); } public static ModInt operator *(ModInt left, ModInt right) { AssertSameMod(left, right); return new ModInt(left.value * right.value, left.mod); } public static ModInt operator *(ModInt mi, long num) { return mi * new ModInt(num, mi.mod); } public static ModInt operator /(ModInt left, ModInt right) { return left * right.Inverse; } public static ModInt operator /(ModInt mi, long num) { return mi / new ModInt(num, mi.mod); } public override bool Equals(object obj) { if (!(obj is ModInt)) return false; var mi = (ModInt)obj; return value == mi.value && mod == mi.mod; } public override int GetHashCode() { return value.GetHashCode(); } public override string ToString() { return value.ToString(); } } public class StreamScanner { static readonly char[] Sep = {' '}; readonly Queue buffer = new Queue(); readonly TextReader textReader; public StreamScanner(TextReader textReader) { this.textReader = textReader; } public T Next(Func parser) { if (buffer.Count != 0) return parser(buffer.Dequeue()); var nextStrings = textReader.ReadLine().Split(Sep, StringSplitOptions.RemoveEmptyEntries); foreach (var nextString in nextStrings) buffer.Enqueue(nextString); return Next(parser); } public T[] Next(Func parser, int x) { var ret = new T[x]; for (var i = 0; i < x; ++i) ret[i] = Next(parser); return ret; } public T[][] Next(Func parser, int x, int y) { var ret = new T[y][]; for (var i = 0; i < y; ++i) ret[i] = Next(parser, x); return ret; } } }