using System;
using System.Linq;
using CompLib.Util;
using System.Threading;
using CompLib.Mathematics;

public class Program
{
    int N;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        // 長さ2Nのかっこ列すべて
        // Trieの最大マッチング

        // 木
        // 2色に塗って少ない方

        // 頂点増え方
        // 以降>しか置けない

        // < >>>>>

        //    0 1 2 3
        // 0: 1
        // 1: 1 1 ... 1
        // 2: 2 2 1 ... 3
        // 3: 5 5 3 1
        // 4:

        var dp = new ModInt[N + 1][];
        for (int i = 0; i <= N; i++)
        {
            dp[i] = new ModInt[i + 1];
        }

        dp[0][0] = 1;
        for (int i = 0; i < N; i++)
        {
            ModInt tmp = 0;
            for (int j = i; j >= 0; j--)
            {
                tmp += dp[i][j];
                dp[i + 1][j + 1] = tmp;
            }
            dp[i + 1][0] = tmp;
        }

        //for (int i = 0; i <= N; i++)
        //{
        //    Console.WriteLine(string.Join(" ", dp[i]));
        //}
        ModInt ans = 0;
        for (int i = 1; i <= N; i++)
        {
            ans += dp[N][i];
        }

        Console.WriteLine(ans);
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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


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

namespace contest
{
    class Program
    {
#if DEBUG
        static readonly TextReader input = File.OpenText(@"../../A/A.in");
        static readonly TextWriter output = File.CreateText(@"../../A/A.out");
#else
        static readonly TextReader input = Console.In;
        static readonly TextWriter output = Console.Out;
#endif

        private static void SolveC()
        {
            //long[] s = input.ReadLine().Split(' ').Select(long.Parse).ToArray();
            int n = int.Parse(input.ReadLine());

            int[][] inp = new int[4*n + 1][];
            for (int i = 0; i <= 4*n; ++i)
            {
                inp[i] = input.ReadLine().Split(' ').Select(int.Parse).ToArray();
            }

            const int Max = 50;

            bool found;
            int xr = 0, yr = 0;
            for (int x = 0; x <= Max; ++x)
            {
                for (int x2 = x; x2 <= Max; ++x2)
                {
                    for (int y = 0; y <= Max; ++y)
                    {
                        int y2 = x2 - x + y;
                        //for (int y2 = y; y2 <= Max; ++y2)
                        {
                            found = false;
                            foreach (int[] xy in inp)
                            {

                                if (!((xy[0] == x && (xy[1] <= y2 && xy[1] >= y)) ||
                                    (xy[0] == x2 && (xy[1] <= y2 && xy[1] >= y))||
                                    (xy[1] == y && (xy[0] <= x2 && xy[0] >= x)) ||
                                    (xy[1] == y2 && (xy[0] <= x2 && xy[0] >= x))))
                                {
                                    xr = xy[0];
                                    yr = xy[1];
                                    if (found)
                                    {
                                        found = false;
                                        break;
                                    }

                                    found = true;
                                }
                            }

                            if (found)
                            {
                                output.Write(xr + " " + yr);
                                return;
                            }
                        }
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            //SolveC();
            SolveC();
            output.Flush();
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.IO;
using System.Text;
using System.Diagnostics;

using static util;
using P = pair<int, int>;

using Binary = System.Func<System.Linq.Expressions.ParameterExpression,
                           System.Linq.Expressions.ParameterExpression,
                           System.Linq.Expressions.BinaryExpression>;
using Unary = System.Func<System.Linq.Expressions.ParameterExpression,
                          System.Linq.Expressions.UnaryExpression>;

class Program {
    static StreamWriter sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
    static Scan sc = new Scan();
    const int M = 1000000007;
    const int M2 = 998244353;
    const long LM = 1L << 60;
    const double eps = 1e-11;
    static void Main(string[] args)
    {
        int n = sc.Int;
        var p = new P[n * 4 + 1];
        var xs = new HashSet<int>();
        var ys = new HashSet<int>();
        for (int i = 0; i < n * 4 + 1; i++)
        {
            p[i] = sc.P;
            xs.Add(p[i].v1);
            ys.Add(p[i].v2);
        }
        foreach (var x1 in xs)
        {
            foreach (var x2 in xs)
            {
                if (x1 >= x2) continue;
                foreach (var y1 in ys)
                {
                    foreach (var y2 in ys)
                    {
                        if (y1 >= y2) continue;
                        var lis = new List<P>();
                        for (int i = 0; i < n * 4 + 1; i++)
                        {
                            if ((p[i].v1 == x1 || p[i].v1 == x2) && y1 <= p[i].v2 && p[i].v2 <= y2 ||
                                (p[i].v2 == y1 || p[i].v2 == y2) && x1 <= p[i].v1 && p[i].v1 <= x2) {
                            }
                            else {
                                lis.Add(p[i]);
                            }
                        }
                        if (lis.Count == 1) {
                            DBG(lis[0]);
                            return;
                        }
                    }
                }
            }
        }

        sw.Flush();
    }

    static void DBG(string a) => Console.WriteLine(a);
    static void DBG<T>(IEnumerable<T> a) => DBG(string.Join(" ", a));
    static void DBG(params object[] a) => DBG(string.Join(" ", a));
    static void Prt(string a) => sw.WriteLine(a);
    static void Prt<T>(IEnumerable<T> a) => Prt(string.Join(" ", a));
    static void Prt(params object[] a) => Prt(string.Join(" ", a));
}
class pair<T, U> : IComparable<pair<T, U>> {
    public T v1;
    public U v2;
    public pair() : this(default(T), default(U)) {}
    public pair(T v1, U v2) { this.v1 = v1; this.v2 = v2; }
    public int CompareTo(pair<T, U> a) {
        int c = Comparer<T>.Default.Compare(v1, a.v1);
        return c != 0 ? c : Comparer<U>.Default.Compare(v2, a.v2);
    }
    public override string ToString() => v1 + " " + v2;
    public void Deconstruct(out T a, out U b) { a = v1; b = v2; }
    public static bool operator>(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) > 0;
    public static bool operator<(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) < 0;
    public static bool operator>=(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) >= 0;
    public static bool operator<=(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) <= 0;
}
static class util {
    public static pair<T, U> make_pair<T, U>(T v1, U v2) => new pair<T, U>(v1, v2);
    public static T sq<T>(T a) => Operator<T>.Multiply(a, a);
    public static T Max<T>(params T[] a) => a.Max();
    public static T Min<T>(params T[] a) => a.Min();
    public static bool inside(int i, int j, int h, int w) => i >= 0 && i < h && j >= 0 && j < w;
    static readonly int[] dd = { 0, 1, 0, -1 };
    static readonly string dstring = "RDLU";
    public static P[] adjacents(this P p) => adjacents(p.v1, p.v2);
    public static P[] adjacents(this P p, int h, int w) => adjacents(p.v1, p.v2, h, w);
    public static pair<P, char>[] adjacents_with_str(int i, int j)
        => Enumerable.Range(0, dd.Length).Select(k => new pair<P, char>(new P(i + dd[k], j + dd[k ^ 1]), dstring[k])).ToArray();
    public static pair<P, char>[] adjacents_with_str(int i, int j, int h, int w)
        => Enumerable.Range(0, dd.Length).Select(k => new pair<P, char>(new P(i + dd[k], j + dd[k ^ 1]), dstring[k])).Where(p => inside(p.v1.v1, p.v1.v2, h, w)).ToArray();
    public static P[] adjacents(int i, int j)
        => Enumerable.Range(0, dd.Length).Select(k => new P(i + dd[k], j + dd[k ^ 1])).ToArray();
    public static P[] adjacents(int i, int j, int h, int w)
        => Enumerable.Range(0, dd.Length).Select(k => new P(i + dd[k], j + dd[k ^ 1])).Where(p => inside(p.v1, p.v2, h, w)).ToArray();
    public static void Assert(bool cond) { if (!cond) throw new Exception(); }
    public static Dictionary<T, int> compress<T>(this IEnumerable<T> a)
        => a.Distinct().OrderBy(v => v).Select((v, i) => new { v, i }).ToDictionary(p => p.v, p => p.i);
    public static Dictionary<T, int> compress<T>(params IEnumerable<T>[] a) => compress(a.Aggregate(Enumerable.Union));
    public static void swap<T>(ref T a, ref T b) where T : struct { var t = a; a = b; b = t; }
    public static void swap<T>(this IList<T> a, int i, int j) where T : struct { var t = a[i]; a[i] = a[j]; a[j] = t; }
    public static T[] copy<T>(this IList<T> a) {
        var ret = new T[a.Count];
        for (int i = 0; i < a.Count; i++) ret[i] = a[i];
        return ret;
    }
}
static class Operator<T> {
    static readonly ParameterExpression x = Expression.Parameter(typeof(T), "x");
    static readonly ParameterExpression y = Expression.Parameter(typeof(T), "y");
    public static readonly Func<T, T, T> Add = Lambda(Expression.Add);
    public static readonly Func<T, T, T> Subtract = Lambda(Expression.Subtract);
    public static readonly Func<T, T, T> Multiply = Lambda(Expression.Multiply);
    public static readonly Func<T, T, T> Divide = Lambda(Expression.Divide);
    public static readonly Func<T, T> Plus = Lambda(Expression.UnaryPlus);
    public static readonly Func<T, T> Negate = Lambda(Expression.Negate);
    public static Func<T, T, T> Lambda(Binary op) => Expression.Lambda<Func<T, T, T>>(op(x, y), x, y).Compile();
    public static Func<T, T> Lambda(Unary op) => Expression.Lambda<Func<T, T>>(op(x), x).Compile();
}

class Scan {
    StreamReader sr;
    public Scan() { sr = new StreamReader(Console.OpenStandardInput()); }
    public Scan(string path) { sr = new StreamReader(path); }
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public string Str => sr.ReadLine().Trim();
    public pair<T, U> Pair<T, U>() {
        T a; U b;
        Multi(out a, out b);
        return new pair<T, U>(a, b);
    }
    public P P => Pair<int, int>();
    public int[] IntArr => StrArr.Select(int.Parse).ToArray();
    public long[] LongArr => StrArr.Select(long.Parse).ToArray();
    public double[] DoubleArr => StrArr.Select(double.Parse).ToArray();
    public string[] StrArr => Str.Split(new[]{' '}, StringSplitOptions.RemoveEmptyEntries);
    bool eq<T, U>() => typeof(T).Equals(typeof(U));
    T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
    T cv<T>(string s) => eq<T, int>()    ? ct<T, int>(int.Parse(s))
                       : eq<T, long>()   ? ct<T, long>(long.Parse(s))
                       : eq<T, double>() ? ct<T, double>(double.Parse(s))
                       : eq<T, char>()   ? ct<T, char>(s[0])
                                         : ct<T, string>(s);
    public void Multi<T>(out T a) => a = cv<T>(Str);
    public void Multi<T, U>(out T a, out U b)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); }
    public void Multi<T, U, V>(out T a, out U b, out V c)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); }
    public void Multi<T, U, V, W>(out T a, out U b, out V c, out W d)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); }
    public void Multi<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]); }
}


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

namespace contest
{
    class Program
    {
#if DEBUG
        static readonly TextReader input = File.OpenText(@"../../A/A.in");
        static readonly TextWriter output = File.CreateText(@"../../A/A.out");
#else
        static readonly TextReader input = Console.In;
        static readonly TextWriter output = Console.Out;
#endif

        private static void SolveC()
        {
            //long[] s = input.ReadLine().Split(' ').Select(long.Parse).ToArray();
            int n = int.Parse(input.ReadLine());
            Dictionary<int, int> x = new Dictionary<int, int>();
            Dictionary<int, int> y = new Dictionary<int, int>();
            int[][] inp = new int[4*n + 1][];
            for (int i = 0; i <= 4*n; ++i)
            {
                int[] s = inp[i] = input.ReadLine().Split(' ').Select(int.Parse).ToArray();
                int count = 0;
                x.TryGetValue(s[0], out count);
                x[s[0]] = count + 1;
                count = 0;
                y.TryGetValue(s[1], out count);
                y[s[1]] = count + 1;
            }

            for (int i = 0; i <= 4 * n; ++i)
            {
                if (x[inp[i][0]] < 2 || y[inp[i][1]] < 2)
                {
                    output.WriteLine(inp[i][0] + " "+ inp[i][1]);
                    return;
                }
            }

            for (int i = 0; i <= 4 * n; ++i)
            {
                if ((inp[i][0] != x.Keys.Min() && inp[i][0] != x.Keys.Max()) &&
                    (inp[i][1] != y.Keys.Min() && inp[i][1] != y.Keys.Max()))
                {
                    output.WriteLine(inp[i][0] + " " + inp[i][1]);
                    return;
                }
            }
        }

        static void Main(string[] args)
        {
            //SolveC();
            SolveC();
            output.Flush();
        }
    }
}


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

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

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

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

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

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


using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using static System.Math;
using System.Numerics;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
//using nint=System.Int32;
static class Program{
	const int mod=(int)1e9+7;
	static void Main(){
		Sc sc=new Sc();
		var t=sc.I;
		StringBuilder sb=new StringBuilder();
		for(int i = 0;i<t;i++) {
			var (n,k)=sc.Tp2<int>();
			long ans=0,e=0,d=1;
			Cb r=new Cb(n<<1);
			for(int j = 0;j<n;j+=2) {e+=r.C1(n,j);}
			if(n%2==1){e++;}
			e%=mod;
			for(int j = 0;j<k;j++) {
				if(n%2==0){ans+=Fp(2,(k-j-1)*n)*d;}
				d*=e;
				d%=mod;
				ans%=mod;
			}
			ans+=d;
			ans%=mod;
			sb.Append(ans+"\n");
		}
		Console.Write(sb);
	}
	static long Fp(long x,long e){
		long r=1;
		while(e>0){
			if((e&1)>0){r*=x;r%=mod;}
			x=x*x%mod;
			e>>=1;
		}
		return r;
	}
}
public class Cb{
	private const int mod=(int)1e9+7;
	public long[] r,f,v;
	public Cb(int n){
		r=new long[n];
		f=new long[n];
		v=new long[n];
		r[0]=r[1]=f[0]=f[1]=v[1]=1;
		for(int i=2;i<n;i++){
			r[i]=r[i-1]*i%mod;
			v[i]=mod-v[mod%i]*(mod/i)%mod;
			f[i]=f[i-1]*v[i]%mod;
		}
	}
	public long C1(long n,long k){return r[n]*(f[k]*f[n-k]%mod)%mod;}
	public long C2(long n,long k){
		long l=1;
		n%=mod;
		for(int i=1;i<=k;i++){l=l*(n-i+1)%mod;l=l*v[i]%mod;}
		return l;
	}
	public long C3(long n,long k){return (r[n]*Mi(r[k]*r[n-k]))%mod;}
	public long P1(long n,long k){return n>=k?r[n]*Mi(r[n-k])%mod:0;}
	public long Mi(long a){
		a=(a+mod)%mod;
		long b=mod,u=1,v=0;
		while(b>0){long t=a/b;a-=t*b;(a,b)=(b,a);u-=t*v;(u,v)=(v,u);}
		u%=mod;
		if(u<0){u+=mod;}
		return u%mod;
	}
}
public class Sc{
	public int I{get{return int.Parse(Console.ReadLine());}}
	public long L{get{return long.Parse(Console.ReadLine());}}
	public double D{get{return double.Parse(Console.ReadLine());}}
	public string S{get{return Console.ReadLine();}}
	public int[] Ia{get{return Array.ConvertAll(Console.ReadLine().Split(),int.Parse);}}
	public long[] La{get{return Array.ConvertAll(Console.ReadLine().Split(),long.Parse);}}
	public double[] Da{get{return Array.ConvertAll(Console.ReadLine().Split(),double.Parse);}}
	public string[] Sa{get{return Console.ReadLine().Split();}}
	public object[] Oa{get{return Console.ReadLine().Split();}}
	public int[] Ia2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),int.Parse);}}
	public int[] Ia3(string a,string b){return Array.ConvertAll((a+Console.ReadLine()+b).Split(),int.Parse);}
	public int[] Ia3(int a){return Array.ConvertAll((Console.ReadLine()+" "+a.ToString()).Split(),int.Parse);}
	public long[] La2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),long.Parse);}}
	public long[] La3(string a,string b){return Array.ConvertAll((a+Console.ReadLine()+b).Split(),long.Parse);}
	public long[] La3(int a){return Array.ConvertAll((Console.ReadLine()+" "+a.ToString()).Split(),long.Parse);}
	public double[] Da2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),double.Parse);}}
	public double[] Da3(string a,string b){return Array.ConvertAll((a+Console.ReadLine()+b).Split(),double.Parse);}
	public T[] Arr<T>(int n,Func<T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f();}return a;}
	public T[] Arr<T>(int n,Func<int,T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i);}return a;}
	public T[] Arr<T>(int n,Func<string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(Console.ReadLine().Split());}return a;}
	public T[] Arr<T>(int n,Func<int,string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i,Console.ReadLine().Split());}return a;}
	public (T,T) Tp2<T>(){var s=Console.ReadLine().Split();return (Ct<T>(s[0]),Ct<T>(s[1]));}
	public (T,T,T) Tp3<T>(){var s=Console.ReadLine().Split();return (Ct<T>(s[0]),Ct<T>(s[1]),Ct<T>(s[2]));}
	public (T,T,T,T) Tp4<T>(){var s=Console.ReadLine().Split();return (Ct<T>(s[0]),Ct<T>(s[1]),Ct<T>(s[2]),Ct<T>(s[3]));}
	public (T1,T2) Tp2<T1,T2>(){var s=Console.ReadLine().Split();return (Ct<T1>(s[0]),Ct<T2>(s[1]));}
	public (T1,T1,T2) Tp3<T1,T2>(){var s=Console.ReadLine().Split();return (Ct<T1>(s[0]),Ct<T1>(s[1]),Ct<T2>(s[2]));}
	private T Ct<T>(string s){return (T)Convert.ChangeType(s,typeof(T));}
}


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

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

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

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

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

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


using System;
using System.Linq;
using CompLib.Util;
using System.Threading;
using System.IO;
using CompLib.Mathematics;

public class Program
{

    BinomialCoefficient C;
    public void Solve()
    {
        C = new BinomialCoefficient(500000);

        var sc = new Scanner();
#if !DEBUG
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
#endif
        int t = sc.NextInt();
        for (int i = 0; i < t; i++)
        {
            Q(sc);
        }
        Console.Out.Flush();
    }

    void Q(Scanner sc)
    {
        int n = sc.NextInt();
        int k = sc.NextInt();

        var dp = new ModInt[k + 1, 2];
        dp[0, 0] = 1;
        ModInt t1 = 0;
        for (int i = 0; i < n; i += 2)
        {
            t1 += C[n, i];
        }
        for (int i = 0; i < k; i++)
        {
            //
            {
                // j=0
                // 全部1
                // and側 1
                // xor側 n%2
                if (n % 2 == 0)
                {
                    dp[i + 1, 0] += dp[i, 0];
                }
                else
                {
                    dp[i + 1, 1] += dp[i, 0];
                }

                // 1じゃないやつある
                // and側0
                // xor側 1の個数偶数
                //
                dp[i + 1, 0] += dp[i, 0] * t1;
            }
            {
                // j =1
                dp[i + 1, 1] += dp[i, 1] * ModInt.Pow(2, n);
            }
        }

        Console.WriteLine(dp[k, 0] + dp[k, 1]);
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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


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

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

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

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

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

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


using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using static System.Math;
using System.Numerics;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
//using nint=System.Int32;
static class Program{
	const int mod=(int)1e9+7;
	static void Main(){
		Sc sc=new Sc();
		var t=sc.I;
		StringBuilder sb=new StringBuilder();
		for(int i = 0;i<t;i++) {
			var (n,k)=sc.Tp2<int>();
			long ans=0,e=0,d=1;
			Cb r=new Cb(n<<1);
			for(int j = 0;j<n;j+=2) {e+=r.C1(n,j);}
			if(n%2==1){e++;}
			e%=mod;
			for(int j = 0;j<k;j++) {
				if(n%2==0){ans+=Fp(2,(k-j-1)*(long)n)*d;}
				d*=e;
				d%=mod;
				ans%=mod;
			}
			ans+=d;
			ans%=mod;
			sb.Append(ans+"\n");
		}
		Console.Write(sb);
	}
	static long Fp(long x,long e){
		long r=1;
		while(e>0){
			if((e&1)>0){r*=x;r%=mod;}
			x=x*x%mod;
			e>>=1;
		}
		return r;
	}
}
public class Cb{
	private const int mod=(int)1e9+7;
	public long[] r,f,v;
	public Cb(int n){
		r=new long[n];
		f=new long[n];
		v=new long[n];
		r[0]=r[1]=f[0]=f[1]=v[1]=1;
		for(int i=2;i<n;i++){
			r[i]=r[i-1]*i%mod;
			v[i]=mod-v[mod%i]*(mod/i)%mod;
			f[i]=f[i-1]*v[i]%mod;
		}
	}
	public long C1(long n,long k){return r[n]*(f[k]*f[n-k]%mod)%mod;}
	public long C2(long n,long k){
		long l=1;
		n%=mod;
		for(int i=1;i<=k;i++){l=l*(n-i+1)%mod;l=l*v[i]%mod;}
		return l;
	}
	public long C3(long n,long k){return (r[n]*Mi(r[k]*r[n-k]))%mod;}
	public long P1(long n,long k){return n>=k?r[n]*Mi(r[n-k])%mod:0;}
	public long Mi(long a){
		a=(a+mod)%mod;
		long b=mod,u=1,v=0;
		while(b>0){long t=a/b;a-=t*b;(a,b)=(b,a);u-=t*v;(u,v)=(v,u);}
		u%=mod;
		if(u<0){u+=mod;}
		return u%mod;
	}
}
public class Sc{
	public int I{get{return int.Parse(Console.ReadLine());}}
	public long L{get{return long.Parse(Console.ReadLine());}}
	public double D{get{return double.Parse(Console.ReadLine());}}
	public string S{get{return Console.ReadLine();}}
	public int[] Ia{get{return Array.ConvertAll(Console.ReadLine().Split(),int.Parse);}}
	public long[] La{get{return Array.ConvertAll(Console.ReadLine().Split(),long.Parse);}}
	public double[] Da{get{return Array.ConvertAll(Console.ReadLine().Split(),double.Parse);}}
	public string[] Sa{get{return Console.ReadLine().Split();}}
	public object[] Oa{get{return Console.ReadLine().Split();}}
	public int[] Ia2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),int.Parse);}}
	public int[] Ia3(string a,string b){return Array.ConvertAll((a+Console.ReadLine()+b).Split(),int.Parse);}
	public int[] Ia3(int a){return Array.ConvertAll((Console.ReadLine()+" "+a.ToString()).Split(),int.Parse);}
	public long[] La2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),long.Parse);}}
	public long[] La3(string a,string b){return Array.ConvertAll((a+Console.ReadLine()+b).Split(),long.Parse);}
	public long[] La3(int a){return Array.ConvertAll((Console.ReadLine()+" "+a.ToString()).Split(),long.Parse);}
	public double[] Da2{get{return Array.ConvertAll(("0 "+Console.ReadLine()+" 0").Split(),double.Parse);}}
	public double[] Da3(string a,string b){return Array.ConvertAll((a+Console.ReadLine()+b).Split(),double.Parse);}
	public T[] Arr<T>(int n,Func<T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f();}return a;}
	public T[] Arr<T>(int n,Func<int,T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i);}return a;}
	public T[] Arr<T>(int n,Func<string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(Console.ReadLine().Split());}return a;}
	public T[] Arr<T>(int n,Func<int,string[],T> f){var a=new T[n];for(int i=0;i<n;i++){a[i]=f(i,Console.ReadLine().Split());}return a;}
	public (T,T) Tp2<T>(){var s=Console.ReadLine().Split();return (Ct<T>(s[0]),Ct<T>(s[1]));}
	public (T,T,T) Tp3<T>(){var s=Console.ReadLine().Split();return (Ct<T>(s[0]),Ct<T>(s[1]),Ct<T>(s[2]));}
	public (T,T,T,T) Tp4<T>(){var s=Console.ReadLine().Split();return (Ct<T>(s[0]),Ct<T>(s[1]),Ct<T>(s[2]),Ct<T>(s[3]));}
	public (T1,T2) Tp2<T1,T2>(){var s=Console.ReadLine().Split();return (Ct<T1>(s[0]),Ct<T2>(s[1]));}
	public (T1,T1,T2) Tp3<T1,T2>(){var s=Console.ReadLine().Split();return (Ct<T1>(s[0]),Ct<T1>(s[1]),Ct<T2>(s[2]));}
	private T Ct<T>(string s){return (T)Convert.ChangeType(s,typeof(T));}
}


using System;
using System.Linq;
using System.Numerics;

namespace CompetitiveProgramming
{
	class Program
	{
		static void Main()
		{
			var cases = int.Parse(Console.ReadLine());
			var output = new ModVal[cases];

			for (int i = 0; i < cases; i++)
			{
				var ints = Console.ReadLine().Split().Select(long.Parse).ToArray();
				var n = ints[0];
				var k = ints[1];
				ModVal ans = Solve(n, k);

				//var s2 = S2(n, k);
				//if (s2 != ans)
				//	Console.WriteLine(s2.Val.ToString() + " " + ans.ToString());

				output[i] = ans;
			}

			output.ToList().ForEach(x => Console.WriteLine(x.Val));
		}

		private static ModVal S2(long n, long k)
		{
			var gaa = new long[n];

			int ab = 0;

			var mask = ~(-1L << (int)k);

			var groups = new int[k];

			var eqa = 0;

			for (long i = 0; i < 1 << ((int)n * (int)k); i++)
			{
				for (int j = 0; j < n; j++)
				{
					gaa[j] = (i >> (j * (int)k)) & mask;
				}

				var anda = gaa.Aggregate(mask, (x, y) => x & y);
				var xora = gaa.Aggregate(0L, (x, y) => x ^ y);

				if (anda == xora)
					eqa++;
				if (anda >= xora)
				{
					ab++;
					//Console.WriteLine(string.Join(' ', gaa));
				}
			}

			Console.WriteLine((ab - eqa).ToString() + ' ' + eqa.ToString());

			return ab;
		}

		private static ModVal Solve(long n, long k)
		{
			// jesli jest nieparzysta to wygrywa gdy na wszystkich bitach jest albo parzysta liczba jedynek albo wszystkie jedynki
			// parzysta liczba jedynek może być na 2^(n-1) sposobow

			ModVal ans;
			if (n % 2 == 1)
			{
				var xa = BigInteger.ModPow(2, n - 1, ModVal.Mod) + 1;
				var va = BigInteger.ModPow(xa, k, ModVal.Mod);
				ans = (long)va;
			}
			else
			{
				// albo wygrywam na ktoryms bicie, albo to co w poprzednim
				var xa = BigInteger.ModPow(2, n - 1, ModVal.Mod) - 1;
				var va = BigInteger.ModPow(xa, k, ModVal.Mod);

				ModVal acc = 0;
				for (int j = 0; j < k; j++)
				{
					var va2 = BigInteger.ModPow(xa, k - j - 1, ModVal.Mod);

					var ga = BigInteger.ModPow(2, j * n, ModVal.Mod)*va2;
					acc = (long)ga + acc;
				}

				//Console.WriteLine((acc).ToString() + ' ' + va.ToString());

				ans = acc + (long)va;
			}

			return ans;
		}
	}

	public struct ModVal
	{
		public static long Mod = 1000000007;
		public readonly long Val;

		public ModVal(long val)
		{
			Val = val % Mod;
		}

		public override bool Equals(object obj) => obj is ModVal && Val == ((ModVal)obj).Val;
		public override int GetHashCode() => Val.GetHashCode();
		public override string ToString() => Val.ToString();
		public static ModVal operator +(ModVal a, ModVal b) => new ModVal(a.Val + b.Val);
		public static ModVal operator -(ModVal a, ModVal b) => new ModVal(a.Val - b.Val + Mod);
		public static ModVal operator *(ModVal a, ModVal b) => new ModVal(a.Val * b.Val);
		public static bool operator ==(ModVal a, ModVal b) => a.Val == b.Val;
		public static bool operator !=(ModVal a, ModVal b) => a.Val != b.Val;
		public static implicit operator ModVal(long a) => new ModVal(a);
	}
}


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

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

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

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

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

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

        }
    }
}


using System;
using System.Linq;
using CompLib.Util;
using System.Threading;
using System.IO;
using CompLib.Mathematics;

public class Program
{

    BinomialCoefficient C;
    public void Solve()
    {
        C = new BinomialCoefficient(500000);

        var sc = new Scanner();
#if !DEBUG
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
#endif
        int t = sc.NextInt();
        for (int i = 0; i < t; i++)
        {
            Q(sc);
        }
        Console.Out.Flush();
    }

    void Q(Scanner sc)
    {
        int n = sc.NextInt();
        int k = sc.NextInt();

        var dp = new ModInt[k + 1, 2];
        dp[0, 0] = 1;
        ModInt t1 = 0;
        for (int i = 0; i < n; i += 2)
        {
            t1 += C[n, i];
        }
        for (int i = 0; i < k; i++)
        {
            //
            {
                // j=0
                // 全部1
                // and側 1
                // xor側 n%2
                if (n % 2 == 0)
                {
                    dp[i + 1, 1] += dp[i, 0];
                }
                else
                {
                    dp[i + 1, 0] += dp[i, 0];
                }

                // 1じゃないやつある
                // and側0
                // xor側 1の個数偶数
                //
                dp[i + 1, 0] += dp[i, 0] * t1;
            }
            {
                // j =1
                dp[i + 1, 1] += dp[i, 1] * ModInt.Pow(2, n);
            }
        }

        Console.WriteLine(dp[k, 0] + dp[k, 1]);
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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


using System;
using System.Linq;
using CompLib.Util;
using System.Threading;
using System.IO;
using CompLib.Mathematics;
using System.Runtime.Intrinsics.Arm;

public class Program
{

    BinomialCoefficient C;
    public void Solve()
    {
        C = new BinomialCoefficient(500000);

        var sc = new Scanner();
#if !DEBUG
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
#endif
        int t = sc.NextInt();
        for (int i = 0; i < t; i++)
        {
            Q(sc);
        }
        Console.Out.Flush();
    }

    void Q(Scanner sc)
    {
        int n = sc.NextInt();
        int k = sc.NextInt();

        var dp = new ModInt[k + 1, 2];
        dp[0, 0] = 1;
        ModInt t1 = 0;
        for (int i = 0; i < n; i += 2)
        {
            t1 += C[n, i];
        }
        for (int i = 0; i < k; i++)
        {
            //
            {
                // j=0
                // 全部1
                // and側 1
                // xor側 n%2
                if (n % 2 == 0)
                {
                    dp[i + 1, 0] += dp[i, 0];
                }
                else
                {
                    dp[i + 1, 1] += dp[i, 0];
                }

                // 1じゃないやつある
                // and側0
                // xor側 1の個数偶数
                //
                dp[i + 1, 0] += dp[i, 0] * t1;
            }
            {
                // j =1
                dp[i + 1, 1] += dp[i, 1] * ModInt.Pow(2, n);
            }
        }

        Console.WriteLine(dp[k, 0] + dp[k, 1]);
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int)1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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


#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

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

#if DEBUG
using System.Diagnostics;
#endif

namespace avC
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;
        const string _delim = "!";

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
            var testNumber = 0;
            var timer = new Stopwatch();
            foreach (var test in GetTests())
            {

                timer.Start();

                var defaultColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"<!-- TEST #{testNumber} -->");
                Console.ForegroundColor = defaultColor;
                Console.SetIn(test);

#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
                Solution();
            }
            finally
            {
                if (_useFileInput)
                {
                    file.Close();
                }
            }

#if DEBUG
                timer.Stop();

                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"<!-- TEST #{testNumber} FINISHED IN {timer.Elapsed.ToString(@"ss\:fff")}-->");
                Console.ForegroundColor = defaultColor;

                timer.Reset();
                testNumber++;
            }
#endif
        }

        static void Solution()
        {
            #region SOLUTION
            var mod = 998244353;
            var d = ReadIntArray();
            var n = d[0];
            var m = d[1];
            var k = d[2];
            var cc = k + 1;
            var dp = new int[n + 1, cc + 1];
            dp[1, 1] = 1;
            for (int i = 2; i < n + 1; i++)
            {
                for (int j = 1; j < cc + 1; j++)
                {
                    if (j > i)
                    {
                        break;
                    }

                    dp[i, j] = dp[i - 1, j];
                    if (j > 1)
                    {
                        dp[i, j] += dp[i - 1, j - 1];
                        dp[i, j] %= mod;
                    }
                }
            }

            var res = dp[n, cc];
            long vs = m;
            for (int i = 0; i < cc - 1; i++)
            {
                vs *= (m - 1);
                vs %= mod;
            }

            vs *= res;
            vs %= mod;

            Console.WriteLine(vs);
            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

        static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }

        static int[] ReadIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] ReadLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
        static IEnumerable<TextReader> GetTests()
        {
            var tests = new List<string>();
            var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
            using (var resource = new StreamReader(Assembly.GetCallingAssembly().GetManifestResourceStream(resName)))
            {
                while (true)
                {
                    var nextText = new StringBuilder();
                    var endOfFile = false;
                    while (true)
                    {
                        var line = resource.ReadLine();

                        endOfFile = line == null;
                        if (endOfFile)
                        {
                            break;
                        }

                        if (line.Equals(_delim, StringComparison.Ordinal))
                        {
                            break;
                        }

                        nextText.AppendLine(line);
                    }

                    yield return new StringReader(nextText.ToString());

                    if (endOfFile)
                    {
                        break;
                    }
                }
            }
        }
#endif
    }
}


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

namespace prC {
    class Program {
#if ONLINE_JUDGE
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024 * 10), System.Text.Encoding.ASCII, false, 1024 * 10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024 * 10), System.Text.Encoding.ASCII, 1024 * 10);
#else
        private static readonly StreamWriter writer = new StreamWriter(@"..\..\output");
        private static readonly StreamReader reader = new StreamReader(@"..\..\input");
#endif

        static void Main(string[] args) {
            ulong module = 998244353;
            int n = NextInt();
            int m = NextInt();
            int k = NextInt();
            ulong[,] dp = new ulong[n, k + 1];
            for (int ni = 0; ni < n; ni++) {
                for (int ki = 0; ki <= k; ki++) {
                    if (ki == 0) {
                        dp[ni, ki] = (ulong) m;
                    }
                    else {
                        if (ni == 0)
                            continue;
                        ulong dp1 = dp[ni - 1, ki - 1] * (ulong) (m - 1);
                        dp1 %= module;
                        dp[ni, ki] = dp1 + dp[ni - 1, ki];
                        dp[ni, ki] %= module;
                    }
                }
            }
            writer.Write(dp[n - 1, k]);
            writer.Flush();
#if !ONLINE_JUDGE
            writer.Close();
#endif
        }
        private static int NextInt() {
            int c;
            int res = 0;
            do {
                c = reader.Read();
                if(c == -1)
                    return res;
            } while(c != '-' && (c < '0' || c > '9'));
            int sign = 1;
            if(c == '-') {
                sign = -1;
                c = reader.Read();
            }
            res = c - '0';
            while(true) {
                c = reader.Read();
                if(c < '0' || c > '9')
                    return res * sign;
                res *= 10;
                res += c - '0';
            }
        }
        private static long NextLong() {
            int c;
            long res = 0;
            do {
                c = reader.Read();
                if(c == -1)
                    return res;
            } while(c != '-' && (c < '0' || c > '9'));
            int sign = 1;
            if(c == '-') {
                sign = -1;
                c = reader.Read();
            }
            res = c - '0';
            while(true) {
                c = reader.Read();
                if(c < '0' || c > '9')
                    return res * sign;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


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

static class UtilityMethods
{
	public static void Swap<T>(ref T a, ref T b)
	{
		T t = a;
		a = b;
		b = t;
	}

	public static int StrToInt(string s)
	{
		int number = 0;
		for (int i = s[0] == '-' ? 1 : 0; i < s.Length; i++)
			number = number * 10 + (s[i] - '0');
		return s[0] == '-' ? -number : number;
	}
	public static long StrToLong(string s)
	{
		long number = 0;
		for (int i = s[0] == '-' ? 1 : 0; i < s.Length; i++)
			number = number * 10 + (s[i] - '0');
		return s[0] == '-' ? -number : number;
	}

	public static string ReadString() => Console.ReadLine();
	public static int ReadInt() => StrToInt(ReadString());
	public static long ReadLong() => StrToLong(ReadString());
	public static double ReadDouble() => double.Parse(ReadString());

	public static string[] ReadStringArray() => ReadString().Split();
	public static int[] ReadIntArray() => Array.ConvertAll(ReadStringArray(), StrToInt);
	public static long[] ReadLongArray() => Array.ConvertAll(ReadStringArray(), StrToLong);
	public static double[] ReadDoubleArray() => ReadStringArray().Select(double.Parse).ToArray();

	public static void WriteLine(object a) => Console.WriteLine(a);
	public static void WriteLineArray<T>(T[] a, string separator)
	{
		if (a.Length < 100)
		{
			Console.WriteLine(String.Join(separator, a));
			return;
		}
		const int MAXLEN = 1000000;
		int len = 0, j = 0;
		System.Text.StringBuilder str;
		string[] b = Array.ConvertAll(a, x => x.ToString());
		for (int i = 0; i < b.Length - 1; i++)
		{
			len += b[i].Length + separator.Length;
			if (len >= MAXLEN)
			{
				str = new System.Text.StringBuilder(len);
				for (; j <= i; j++)
				{
					str.Append(b[j]);
					str.Append(separator);
				}
				Console.Write(str);
				len = 0;
			}
		}
		str = new System.Text.StringBuilder(len);
		for (; j < b.Length - 1; j++)
		{
			str.Append(b[j]);
			str.Append(separator);
		}
		Console.Write(str);
		Console.WriteLine(b.Last());
	}
}

class Program
{
	static BigInteger Factorial(int n)
	{
		BigInteger res = new BigInteger(1);
		for (int i = 2; i <= n; i++)
			res *= i;
		return res;
	}
	static void Main()
	{
		int[] data = UtilityMethods.ReadIntArray();
		int n = data[0], m = data[1], k = data[2];
		BigInteger ans = Factorial(n - 1) / Factorial(n - 1 - k) / Factorial(k) * m * BigInteger.Pow(m - 1, k);
		Console.WriteLine(ans % 998244353);
		Console.ReadLine();
	}
}


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

namespace codeforces
{

    class Program
    {
        const int N = 2000;
        const int MOD = 998244353;

        static int n, m, k;
        static int[,] dp = new int[N, N];

        static int mul(int a, int b)
        {
            return (int) ((1L * a * b) % MOD);
        }

        static int add(int a, int b)
        {
            int result = a + b;
            if (result >= MOD)
            {
                result -= MOD;
            }
            return result;
        }

        static void Main(string[] args)
        {
            var s = Console.ReadLine().Split(' ');
            n = int.Parse(s[0]);
            m = int.Parse(s[1]);
            k = int.Parse(s[2]);
            for (int i = 0; i < n; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    dp[i, j] = 0;
                }
            }
            dp[0, 0] = m;
            for (int i = 1; i < n; ++i)
            {
                for (int j = 0; j <= i; ++j)
                {
                    dp[i, j] = j == 0
                        ? dp[i - 1, j]
                        : add(dp[i - 1, j], mul(m - 1, dp[i - 1, j - 1]));
                }
            }
            Console.WriteLine(dp[n - 1, k]);
        }
    }
}


using System;
using System.IO;
using System.Text;

namespace Colorful_Bricks
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static long Solve(string[] args)
        {
            int n = Next();
            int m = Next();
            int k = Next();

            const int mod = 998244353;

            var dp = new long[k + 1];
            dp[0] = m;

            for (int i = 2; i <= n; i++)
            {
                for (int j = dp.Length - 1; j > 0; j--)
                {
                    dp[j] = (dp[j] + dp[j - 1]*(m - 1))%mod;
                }
            }

            return dp[k];
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


/*
csc -debug C.cs && mono --debug C.exe <<< "3 3 0"
*/

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

public class HelloWorld {
    static public void Main () {
        SolveCodeForces();
    }

    public static void SolveCodeForces() {
        var sc = new Scanner();
        var n = sc.NextInt();
        var m = sc.NextUlong();
        var k = sc.NextInt();

        const ulong MOD = 998244353ul;

        var S = new ulong[n, k+1];
        S[0, 0] = m;

        for (var i = 1; i < n; i++) {

            S[i, 0] = m;

            for (var j = 1; j <= k; j++) {
                S[i, j] = (  S[i-1, j-1] * (m-1) + S[i-1, j]  ) % MOD;
            }

        }

        System.Console.WriteLine(S[n-1, k]);
    }
}

public static class Helpers {
    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }

    public static T ElementWithMax<T>(this IEnumerable<T> seq, Func<T, long> func) {
        var bi = default(T);
        var bv = long.MinValue;
        foreach (var item in seq) {
            var v = func(item);
            if (v > bv) {
                bi = item;
                bv = v;
            }
        }
        return bi;
    }

    public static IEnumerable<int> IndicesWhere<T>(this IEnumerable<T> seq, Func<T, bool> cond) {
        var i = 0;
        foreach (var item in seq) {
            if (cond(item)) yield return i;
            i++;
        }
    }
}

public class Scanner
{
    private string[] line = new string[0];
    private int index = 0;

    public string Next() {
        if (line.Length <= index) {
            line = Console.ReadLine().Split(' ');
            index = 0;
        }
        var res = line[index];
        index++;
        return res;
    }

    public int NextInt() {
        return int.Parse(Next());
    }

    public long NextLong() {
        return long.Parse(Next());
    }

    public ulong NextUlong() {
        return ulong.Parse(Next());
    }

    public string[] Array() {
        line = Console.ReadLine().Split(' ');
        index = line.Length;
        return line;
    }

    public int[] IntArray() {
        var array = Array();
        var result = new int[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = int.Parse(array[i]);
        return result;
    }

    public long[] LongArray() {
        var array = Array();
        var result = new long[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = long.Parse(array[i]);
        return result;
    }

    public ulong[] UlongArray() {
        var array = Array();
        var result = new ulong[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = ulong.Parse(array[i]);
        return result;
    }
}


using System;
using System.IO;
using System.Text;

namespace Colorful_Bricks
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static long Solve(string[] args)
        {
            int n = Next();
            int m = Next();
            int k = Next();

            const int mod = 998244353;

            var dp = new long[k + 1];
            dp[0] = m;

            for (int i = 2; i <= n; i++)
            {
                for (int j = 1; j < dp.Length; j++)
                {
                    dp[j] = (dp[j] + dp[j - 1]*(m - 1))%mod;
                }
            }

            return dp[k];
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


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

namespace prC {
    class Program {
#if ONLINE_JUDGE
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024 * 10), System.Text.Encoding.ASCII, false, 1024 * 10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024 * 10), System.Text.Encoding.ASCII, 1024 * 10);
#else
        private static readonly StreamWriter writer = new StreamWriter(@"..\..\output");
        private static readonly StreamReader reader = new StreamReader(@"..\..\input");
#endif

        static void Main(string[] args) {
            ulong module = 998244353;
            int n = NextInt();
            int m = NextInt();
            int k = n - NextInt() - 1;
            ulong[,] dp = new ulong[n, k + 1];
            for (int ni = 0; ni < n; ni++) {
                for (int ki = 0; ki <= k; ki++) {
                    if (ni == 0 && ki == 0) {
                        dp[0, 0] = (ulong) m;
                        continue;
                    }
                    if (ki == 0) {
                        ulong dp1 = dp[ni - 1, ki] * (ulong) Math.Max(m - ni, 0);
                        dp1 %= module;
                        dp[ni, ki] = dp1;
                    }
                    else {
                        ulong dp1 = ki >= ni ? 0 : dp[ni - 1, ki] * (ulong) (m - 1);
                        dp1 %= module;
                        dp1 = ni == 0 ? 0 : dp[ni - 1, ki - 1] + dp1;
                        dp1 %= module;
                        dp[ni, ki] = dp1;
                    }
                }
            }
            writer.Write(dp[n - 1, k]);
            writer.Flush();
#if !ONLINE_JUDGE
            writer.Close();
#endif
        }
        private static int NextInt() {
            int c;
            int res = 0;
            do {
                c = reader.Read();
                if(c == -1)
                    return res;
            } while(c != '-' && (c < '0' || c > '9'));
            int sign = 1;
            if(c == '-') {
                sign = -1;
                c = reader.Read();
            }
            res = c - '0';
            while(true) {
                c = reader.Read();
                if(c < '0' || c > '9')
                    return res * sign;
                res *= 10;
                res += c - '0';
            }
        }
        private static long NextLong() {
            int c;
            long res = 0;
            do {
                c = reader.Read();
                if(c == -1)
                    return res;
            } while(c != '-' && (c < '0' || c > '9'));
            int sign = 1;
            if(c == '-') {
                sign = -1;
                c = reader.Read();
            }
            res = c - '0';
            while(true) {
                c = reader.Read();
                if(c < '0' || c > '9')
                    return res * sign;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


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

static class UtilityMethods
{
	public static void Swap<T>(ref T a, ref T b)
	{
		T t = a;
		a = b;
		b = t;
	}

	public static int StrToInt(string s)
	{
		int number = 0;
		for (int i = s[0] == '-' ? 1 : 0; i < s.Length; i++)
			number = number * 10 + (s[i] - '0');
		return s[0] == '-' ? -number : number;
	}
	public static long StrToLong(string s)
	{
		long number = 0;
		for (int i = s[0] == '-' ? 1 : 0; i < s.Length; i++)
			number = number * 10 + (s[i] - '0');
		return s[0] == '-' ? -number : number;
	}

	public static string ReadString() => Console.ReadLine();
	public static int ReadInt() => StrToInt(ReadString());
	public static long ReadLong() => StrToLong(ReadString());
	public static double ReadDouble() => double.Parse(ReadString());

	public static string[] ReadStringArray() => ReadString().Split();
	public static int[] ReadIntArray() => Array.ConvertAll(ReadStringArray(), StrToInt);
	public static long[] ReadLongArray() => Array.ConvertAll(ReadStringArray(), StrToLong);
	public static double[] ReadDoubleArray() => ReadStringArray().Select(double.Parse).ToArray();

	public static void WriteLine(object a) => Console.WriteLine(a);
	public static void WriteLineArray<T>(T[] a, string separator)
	{
		if (a.Length < 100)
		{
			Console.WriteLine(String.Join(separator, a));
			return;
		}
		const int MAXLEN = 1000000;
		int len = 0, j = 0;
		System.Text.StringBuilder str;
		string[] b = Array.ConvertAll(a, x => x.ToString());
		for (int i = 0; i < b.Length - 1; i++)
		{
			len += b[i].Length + separator.Length;
			if (len >= MAXLEN)
			{
				str = new System.Text.StringBuilder(len);
				for (; j <= i; j++)
				{
					str.Append(b[j]);
					str.Append(separator);
				}
				Console.Write(str);
				len = 0;
			}
		}
		str = new System.Text.StringBuilder(len);
		for (; j < b.Length - 1; j++)
		{
			str.Append(b[j]);
			str.Append(separator);
		}
		Console.Write(str);
		Console.WriteLine(b.Last());
	}
}

class Program
{
	static BigInteger Factorial(int n)
	{
		BigInteger res = new BigInteger(1);
		for (int i = 2; i <= n; i++)
			res *= i;
		return res;
	}
	static void Main()
	{
		int[] data = UtilityMethods.ReadIntArray();
		int n = data[0], m = data[1], k = data[2];
		BigInteger ans = Factorial(n - 1) / Factorial(n - 1 - k) / Factorial(k) * m * BigInteger.Pow(m - 1, k - 1);
		Console.WriteLine(ans % 998244353);
		Console.ReadLine();
	}
}


using System;

namespace Обрамление_дверей
{
    class Program
    {
        static void Main(string[] args)
        {
            int barLength = int.Parse(Console.ReadLine());
            int borderLength = int.Parse(Console.ReadLine());
            int upperBorderLength = int.Parse(Console.ReadLine());

            int scrap, barNum = 0, aNum=0,bNum=0;

            while (true)
            {
                if (upperBorderLength <= borderLength && bNum < 2 || aNum >= 4 && bNum < 2)
                {
                    scrap = barLength;
                    barNum++;
                    scrap -= upperBorderLength;
                    bNum++;
                }
                else if(aNum<4 || bNum>=2 && aNum<4)
                {
                    scrap = barLength;
                    barNum++;
                    scrap -= borderLength;
                    aNum++;
                }
                else
                {
                    break;
                }
                while (true)
                {
                    int aTmp = scrap - borderLength;
                    int bTmp = scrap - upperBorderLength;
                    if (aTmp>=0&&aTmp<=bTmp&&aNum<4 || aTmp>=0&&aNum<4&&bNum>=2 || bTmp<0 && aNum<4 && aTmp>=0)
                    {
                        scrap = aTmp;
                        aNum++;
                    }
                    else if (bTmp>=0&&bNum<2 || bTmp >= 0 && bNum < 2 && aNum >= 4 || aTmp<0 && bTmp<2 && bTmp>=0)
                    {
                        scrap = bTmp;
                        bNum++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            Console.WriteLine(barNum);
        }
    }
}


using System;
using System.IO;
using System.Text;

namespace Door_Frames
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static int Solve(string[] args)
        {
            int n = Next();
            int a = Next();
            int b = Next();

            int max = 1 << 6;

            int min = 6;
            for (int i = 0; i < max; i++)
            {
                if (SparseBitcount(i) == 2)
                {
                    int ii = i;
                    int count = 1;
                    int remain = n;
                    for (int j = 0; j < 6; j++)
                    {
                        if ((ii & 1) == 1)
                        {
                            if (remain >= b)
                            {
                                remain -= b;
                            }
                            else
                            {
                                count++;
                                remain = n - b;
                            }
                        }
                        else
                        {
                            if (remain >= a)
                            {
                                remain -= a;
                            }
                            else
                            {
                                count++;
                                remain = n - a;
                            }
                        }
                        ii >>= 1;
                    }
                    min = Math.Min(min, count);
                }
            }

            return min;
        }

        private static int SparseBitcount(int n)
        {
            int count = 0;
            while (n != 0)
            {
                count++;
                n &= (n - 1);
            }
            return count;
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


using System;
using System.Collections.Generic;

namespace CodeForceCs
{
    static class Program
    {
        static void Main(string[] args)
        {
            Solver solver = new _Q910B();
            solver.SolveProblem();
            //Console.ReadKey();
        }
    }

    abstract class Solver
    {
        abstract public void SolveProblem();
    }

    class _Q910B : Solver
    {
        int n, a, b;
        List<int> need = new List<int>();
        override public void SolveProblem()
        {
            n = int.Parse(Console.ReadLine());
            a = int.Parse(Console.ReadLine());
            b = int.Parse(Console.ReadLine());

            Console.WriteLine(GetResult());
        }

        int GetResult()
        {

            if (n >= 4 * a + 2 * b)
                return 1;

            if (n >= 2 * a + b)
                return 2;

            if (a >= b)
            {
                if (n >= 2 * a)
                    return 3;

                if (n >= a + b)
                    return 4;

                if (n >= 2 * b)
                    return 5;
            }
            else
            {
                if (n >= a + b || n >= 4 * a)
                    return 3;

                if (n >= 2 * a)
                    return 4;
            }
            return 6;
        }
    }

}


using System;
using System.Collections.Generic;

namespace CodeForceCs
{
    static class Program
    {
        static void Main(string[] args)
        {
            Solver solver = new _Q910B();
            solver.SolveProblem();
            //Console.ReadKey();
        }
    }

    abstract class Solver
    {
        abstract public void SolveProblem();
    }

    class _Q910B : Solver
    {
        int n, a, b;
        List<int> need = new List<int>();
        override public void SolveProblem()
        {
            n = int.Parse(Console.ReadLine());
            a = int.Parse(Console.ReadLine());
            b = int.Parse(Console.ReadLine());

            Console.WriteLine(GetResult());
        }

        int GetResult()
        {

            if (n >= 4 * a + 2 * b)
                return 1;

            if (n >= 2 * a + b)
                return 2;

            if (a >= b)
            {
                if (n >= 2 * a)
                    return 3;

                if (n >= a + b)
                    return 4;

                if (n >= 2 * b)
                    return 5;
            }
            else
            {
                if (n >= a + b)
                    return 3;

                if (n >= 2 * a)
                    return 4;
            }
            return 6;
        }
    }

}


using System;

namespace Обрамление_дверей
{
    class Program
    {
        static void Main(string[] args)
        {
            int barLength = int.Parse(Console.ReadLine());
            int borderLength = int.Parse(Console.ReadLine());
            int upperBorderLength = int.Parse(Console.ReadLine());

            int scrap, barNum = 0, aNum=0,bNum=0;

            while (true)
            {
                if (upperBorderLength<=borderLength && bNum<2)
                {
                    scrap = barLength;
                    barNum++;
                    scrap -= upperBorderLength;
                    bNum++;
                }
                else if(aNum<4)
                {
                    scrap = barLength;
                    barNum++;
                    scrap -= borderLength;
                    aNum++;
                }
                else
                {
                    break;
                }
                while (true)
                {
                    int aTmp = scrap - borderLength;
                    int bTmp = scrap - upperBorderLength;
                    if (aTmp>=0&&aTmp<=bTmp&&aNum<4 || aTmp>=0&&aNum<4&&bNum>=2)
                    {
                        scrap = aTmp;
                        aNum++;
                    }
                    else if (bTmp>=0&&bNum<2 || bTmp >= 0 && bNum < 2 && aNum >= 4)
                    {
                        scrap = bTmp;
                        bNum++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            Console.WriteLine(barNum);
        }
    }
}


using System;

namespace Обрамление_дверей
{
    class Program
    {
        static void Main(string[] args)
        {
            int barLength = int.Parse(Console.ReadLine());
            int borderLength = int.Parse(Console.ReadLine());
            int upperBorderLength = int.Parse(Console.ReadLine());

            int scrap = barLength, barNum = 1, aNum=0,bNum=0;

            do
            {
                if (scrap >= upperBorderLength && bNum < 2)
                {
                    bNum++;
                    scrap -= upperBorderLength;
                }
                else if (scrap >= borderLength && aNum < 4)
                {
                    aNum++;
                    scrap -= borderLength;
                }
                else
                {
                    scrap = barLength;
                    barNum++;
                }
            }
            while (aNum<4||bNum<2);

            Console.WriteLine(barNum);
        }
    }
}


using System;

namespace Обрамление_дверей
{
    class Program
    {
        static void Main(string[] args)
        {
            int barLength = int.Parse(Console.ReadLine());
            int borderLength = int.Parse(Console.ReadLine());
            int upperBorderLength = int.Parse(Console.ReadLine());

            int scrap, barNum = 0, aNum=0,bNum=0;

            while (true)
            {
                if (upperBorderLength <= borderLength && bNum < 2 || aNum >= 4 && bNum < 2)
                {
                    scrap = barLength;
                    barNum++;
                    scrap -= upperBorderLength;
                    bNum++;
                }
                else if(aNum<4 || bNum>=2 && aNum<4)
                {
                    scrap = barLength;
                    barNum++;
                    scrap -= borderLength;
                    aNum++;
                }
                else
                {
                    break;
                }
                while (true)
                {
                    int aTmp = scrap - borderLength;
                    int bTmp = scrap - upperBorderLength;
                    if (aTmp>=0&&aTmp<=bTmp&&aNum<4 || aTmp>=0&&aNum<4&&bNum>=2)
                    {
                        scrap = aTmp;
                        aNum++;
                    }
                    else if (bTmp>=0&&bNum<2 || bTmp >= 0 && bNum < 2 && aNum >= 4)
                    {
                        scrap = bTmp;
                        bNum++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            Console.WriteLine(barNum);
        }
    }
}


using System;

namespace Обрамление_дверей
{
    class Program
    {
        static void Main(string[] args)
        {
            int barLength = int.Parse(Console.ReadLine());
            int borderLength = int.Parse(Console.ReadLine());
            int upperBorderLength = int.Parse(Console.ReadLine());

            int scrap = barLength, barNum = 1, aNum=0,bNum=0;

            do
            {
                if (scrap>=borderLength&&aNum<4)
                {
                    aNum++;
                    scrap -= borderLength;
                }
                else if (scrap>=upperBorderLength&&bNum<2)
                {
                    bNum++;
                    scrap -= upperBorderLength;
                }
                else
                {
                    scrap = barLength;
                    barNum++;
                }
            }
            while (aNum<4||bNum<2);

            Console.WriteLine(barNum);
        }
    }
}


using System;
using System.Collections.Generic;

namespace CodeForceCs
{
    static class Program
    {
        static void Main(string[] args)
        {
            Solver solver = new _Q910B();
            solver.SolveProblem();
            Console.ReadKey();
        }
    }

    abstract class Solver
    {
        abstract public void SolveProblem();
    }

    class _Q910B : Solver
    {
        int n, a, b, result;
        List<int> need = new List<int>();
        override public void SolveProblem()
        {
            n = int.Parse(Console.ReadLine());
            a = int.Parse(Console.ReadLine());
            b = int.Parse(Console.ReadLine());

            Console.Write(GetResult());
        }

        int GetResult()
        {

            if (n >= 4 * a + 2 * b)
                return 1;

            if (n >= 2 * a + b)
                return 2;

            if (a >= b)
            {
                if (n >= 2 * a)
                    return 3;

                if (n >= a + b)
                    return 4;

                if (n >= 2 * b)
                    return 5;
            }
            else
            {
                if (n >= a + b)
                    return 3;

                if (n >= 2 * a)
                    return 4;
            }
            return 6;
        }
    }

}