import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.StringTokenizer;

import static java.lang.Math.*;

public class Main {
    BufferedReader br;
    StringTokenizer in;
    PrintWriter pw;
    Random r;
    int INF = (int) 1e9;
    int mod = (int) (1e9 + 7);
    //int p = 26;
    ArrayList<Integer> g[];

    void end(int a, int n) {
        if ((int) Math.pow(2, a) != n) pw.print(a);
        else pw.print("Final!");
        pw.close();
        System.exit(0);
    }

    class node {
        int val;
        int m;
        int size;
        int prior;
        node L;
        node R;

        public node(int v) {
            val = v;
            prior = r.nextInt();
            size = 1;
            L = null;
            R = null;
        }
    }

    int sgs(node c) {
        if (c == null) return 0;
        return c.size;
    }

    int sgm(node c) {
        if (c == null) return INF;
        return c.m;
    }

    void relax(node c) {
        if (c == null) return;
        c.size = 1 + sgs(c.L) + sgs(c.R);
    }

    class pair implements Comparable<pair> {
        int a;
        int b;

        public pair(int aa, int bb) {
            a = aa;
            b = bb;
        }

        @Override
        public int compareTo(pair o) {
            if (a != o.a) return a - o.a;
            return b - o.b;
        }
    }

    class road {
        int to;
        int w;

        public road(int tto, int ww) {
            to = tto;
            w = ww;
        }

        public road() throws IOException {
            to = nextInt();
            w = nextInt();
        }
    }

    void readG(int n, int m) throws IOException {
        g = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            g[i] = new ArrayList<>();
        }
        for (int i = 0; i < m; i++) {
            int a = nextInt() - 1;
            int b = nextInt() - 1;
            int w = nextInt();
//            g[a].add(new road(b, w));
//            g[b].add(new road(a, w));
        }
    }

    int p[];
    int d[];

    void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        event[] p = new event[n * 2];
        for (int i = 0; i < n; i++) {
            int l = nextInt();
            int r = nextInt();
            p[i] = new event(l, 1);
            p[i + n] = new event(r, -1);
        }
        int q = p.length;
        int b = 0;
        Arrays.sort(p);
        int bal[] = new int[m + 1];
        int prev = 0;
        for (int i = 0; i < q; i++) {
            event a = p[i];
            if (a.t == -1) {
                for (int j = prev + 1; j <= a.time; j++) {
                    bal[j] = b;
                }
                prev = a.time;
            } else {
                for (int j = prev + 1; j < a.time; j++) {
                    bal[j] = b;
                }
                prev = a.time - 1;
            }
            b += a.t;
        }
//        for (int i = 1; i <= m; i++) {
//            pw.print(bal[i]);
//        }
        int revbal[] = new int[m + 1];
        for (int i = 1; i <= m; i++) {
            revbal[i] = bal[m + 1 - i];
        }
        int nvp[] = getnvp(bal);
        int rnvp[] = getnvp(revbal);
        int ans = 0;
        for (int i = 1; i <= m; i++) {
            int z = nvp[i];
            int w = rnvp[m - i];
            int sum = z + w;
            ans = max(ans, sum);
        }
        pw.print(ans);
    }

    int[] getnvp(int a[]) {
        int n = a.length;
        int d[] = new int[n + 1];
        int ans[] = new int[n];
        Arrays.fill(d, INF);
        d[0] = -INF;
        int last = 0;
        for (int i = 1; i < n; i++) {
            ans[i] = ans[i - 1];
            int c = a[i];
            int l = 0;
            int r = last + 1;
            while (l + 1 != r) {
                int m = (l + r) / 2;
                if (d[m] <= c) l = m;
                else r = m;
            }
            if (d[r] == INF) {
                ans[i]++;
                last++;
            }
            d[r] = min(d[r], c);
        }
        return ans;
    }

    class event implements Comparable<event> {
        int time;
        int t;

        public event(int ttime, int tt) {
            time = ttime;
            t = tt;
        }

        @Override
        public int compareTo(event o) {
            if (time != o.time) return time - o.time;
            else return o.t - t;
        }
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }

    void run() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new OutputStreamWriter(System.out));
        r = new Random(5);
        solve();
        pw.close();
    }

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

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

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


import java.io.BufferedReader;
// import java.io.FileInputStream;
// import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Random;
import java.util.StringTokenizer;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.round;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;
import static java.util.Collections.reverseOrder;
import static java.util.Collections.sort;
import static java.util.Comparator.comparingInt;

public class Solution {
    FastScanner in;
    PrintWriter out;

    private void solve() throws IOException {
        int n = in.nextInt(), k = in.nextInt();
        int[] h = new int[n];
        for (int i = 0; i < n; i++)
            h[i] = in.nextInt();

        int any = 0;
        for (int i = 0; i < n; i++)
            if (h[i] == h[(i + 1) % n])
                any++;

        n -= any;
        k -= 2;

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

        long ans = 0, f = 1;
        for (int spec = 1; spec <= n; spec++) {
            if (spec > 2) {
                if (spec % 2 == 1)
                    f = (f * 2 % mod + Cmod(spec / 2, spec - 1)) % mod;
                else
                    f = (f * 2 % mod + mod - Cmod(spec / 2 - 1, spec - 1)) % mod;
            }
            ans = (ans + binpowmod(k, n - spec) * Cmod(spec, n) % mod * f % mod) % mod;
        }

        out.println(ans * binpowmod(k + 2, any) % mod);
    }

    long mod = 998244353;
    long[] factmod;

    long Cmod(int k, int n) {
        return factmod[n] * binpowmod(factmod[k] * factmod[n - k], mod - 2) % mod;
    }

    long binpowmod(long a, long n) {
        long res = 1;
        a %= mod;
        n %= mod - 1;
        while (n > 0) {
            if (n % 2 == 1)
                res = (res * a) % mod;
            a = (a * a) % mod;
            n /= 2;
        }
        return res;
    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

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

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

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

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

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

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

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

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

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream(".in"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream(".out"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Solution().run();
    }
}


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

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {
    static long mod = 998244353;
    static long fact[];
    static long inv[];

    static long pow(long a, long n) {
        if (n == 0) return 1;
        if (n == 1) return a;
        if ((n & 1) == 0) {
            long np = pow(a, n / 2);
            return (np * np)%mod;
        }
        return a % mod * pow(a, n - 1) % mod;
    }

    static long c(int n, int k) {
        return ((fact[n] * inv[k]) % mod * inv[n - k]) % mod;
    }

    public static void main(String[] args) throws IOException {
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        int k = in.nextInt();
//        if(n == 5 && k == 5){
//            out.println(1000);
//            out.close();
//            return;
//        }
        array a = new array(n);
        a.scan(in);
        long h[] = a.a;
        long _h[] = a.right_shift(1);
        int eq = 0;
        for (int i = 0; i < n; i++) {
            if (h[i] == _h[i]) ++eq;
        }
        inv = new long[n + 1];
        fact = new long[n + 1];
        fact[1] = inv[1] = fact[0] = inv[0] = 1;
        for (int i = 2; i < n + 1; i++) {
            fact[i] = fact[i - 1] * i;
            fact[i] %= mod;
            inv[i] = pow(fact[i], mod - 2);
            inv[i] %= mod;
        }
        long f = max(1, pow(k, eq));
        int N = n - eq;
        long ans = 0;
        long sum = 1;
        for (int i = 1; i <= N; i++) {
            ans = (ans + sum * pow(k - 2, N - i) % mod * c(N, i)) % mod;
            sum = sum * 2 % mod;
            if (i % 2 != 0) {
                sum = (sum + mod - c(i, i / 2)) % mod;
            }
            else {
                sum = (sum + c(i, i / 2)) % mod;
            }
        }
        ans = ans * f % mod;
        out.println(ans);
        out.close();
    }
}

class RANDOMIZER {
    static Random rnd = new Random();

    static int randomize() {
        return rnd.nextInt();
    }
}

class array {
    long a[];

    array(long a[]) {
        this.a = a;
    }

    array(int n) {
        a = new long[n];
    }

    void shuffle() {
        for (int i = 0; i < a.length; i++) {
            int id1 = ((RANDOMIZER.randomize() % a.length) + a.length) % a.length;
            int id2 = ((RANDOMIZER.randomize() % a.length) + a.length) % a.length;
            long t = a[id1];
            a[id1] = a[id2];
            a[id2] = t;
        }
    }

    void reverse(int l, int r) {
        for (int i = l; i < l + (r - l + 1) >> 1; i++) {
            long t = a[i];
            a[i] = a[r - i];
            a[r - i] = t;
        }
    }

    long[] right_shift(int shift) {
        long aa[] = new long[a.length];
        for (int i = 0; i < a.length; i++) {
            aa[(i + shift) % a.length] = a[i];
        }
        return aa;
    }

    void add(int l, int r, long val) {
        for (int i = l; i <= r; i++) {
            a[i] += val;
        }
    }

    void print(PrintWriter out) {
        for (int i = 0; i < a.length; i++) {
            out.print(a[i] + " ");
        }
    }

    void copy(long t[]) {
        for (int i = 0; i < a.length; i++) {
            a[i] = t[i];
        }
    }

    void scan(FastScanner in) throws IOException {
        for (int i = 0; i < a.length; i++) {
            a[i] = in.nextLong();
        }
    }

    long getSum() {
        long sum = 0;
        long md = (long) 1e16;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
            sum %= md;
        }
        return sum;
    }

    long getMin() {
        long min = Long.MAX_VALUE;
        for (int i = 0; i < a.length; i++) {
            min = min(min, a[i]);
        }
        return min;
    }

    long getMax() {
        long max = Long.MIN_VALUE;
        for (int i = 0; i < a.length; i++) {
            max = max(max, a[i]);
        }
        return max;
    }

    int ceilingID(long val) {
        int l = 0;
        int r = a.length - 1;
        while (l + 1 != r) {
            int m = (l + r) >> 1;
            if (a[m] >= val) r = m;
            else l = m;
        }
        int pr = l;
        if (pr > 0 && a[pr - 1] >= val) pr--;
        if (a[pr] < val) pr++;
        if (pr < a.length && a[pr] < val) pr++;
        return pr;
    }
}

class dsu {
    int p[];
    int max[];

    dsu(int n) {
        p = new int[n];
        max = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i;
            max[i] = i;
        }
    }

    int get(int a) {
        if (p[a] == a) return a;
        return p[a] = get(p[a]);
    }

    void merge(int a, int b) {
        a = get(a);
        b = get(b);
        if (a != b) {
            p[a] = b;
            max[b] = max(max[a], max[b]);
        }
    }
}

class vertex {
    int next[];
}

class trie {
    vertex t[];
    int sz = 1;
    int k;

    trie(int k) {
        this.k = k;
        t = new vertex[300000];
        for (int i = 0; i < t.length; i++) {
            t[i] = new vertex();
            t[i].next = new int[k];
            for (int j = 0; j < k; j++) {
                t[i].next[j] = -1;
            }
        }
    }

    void add(String s, int id) {
        int v = 0;
        for (int i = 0; i < s.length(); i++) {
            char rc = (char) (s.charAt(i) - 'a');
            if (t[v].next[rc] == -1) {
                t[v].next[rc] = sz++;
            }
            v = t[v].next[rc];
        }
    }
}

class StringHelper {
    char[] s;
    long hash[];
    long px[];
    long mod = (int) 1e9 + 7;
    long x = 255;
    int n;

    public StringHelper(String s) {
        this.s = s.toCharArray();
        n = s.length();
    }

    int[] pi() {
        int pi[] = new int[n];
        for (int i = 1; i < n; i++) {
            int j = pi[i - 1];
            while (j > 0 && s[i] != s[j]) j = pi[j - 1];
            pi[i] = s[i] == s[j] ? j + 1 : j;
        }
        return pi;
    }

    void calcHash() {
        hash = new long[n + 1];
        px = new long[n + 3];
        px[0] = 1;
        for (int i = 1; i < n + 3; i++) {
            px[i] = px[i - 1] * x % mod;
        }
        for (int i = 1; i < n + 1; i++) {
            hash[i] = (hash[i - 1] * x % mod + s[i - 1] + mod) % mod;
        }
    }

    long getHash(int l, int r) {
        return (hash[r + 1] - hash[l] * px[r - l + 1] % mod + mod) % mod;
    }
}

class IMPLICITDT {
    long val;
    int y;
    int sz;
    IMPLICITDT l, r;

    static int getSize(IMPLICITDT t) {
        return t == null ? 0 : t.sz;
    }

    private static void recalc(IMPLICITDT t) {
        if (t == null) return;
        int LSZ = t.l == null ? 0 : t.l.sz;
        int RSZ = t.r == null ? 0 : t.r.sz;
        t.sz = LSZ + RSZ + 1;
    }

    IMPLICITDT() {
    }

    IMPLICITDT(long cost, int y, IMPLICITDT l, IMPLICITDT r) {
        this.val = cost;
        this.y = y;
        this.l = l;
        this.r = r;
        recalc(this);
    }

    IMPLICITDT(long cost, int y) {
        this.val = cost;
        this.y = y;
        recalc(this);
    }

    static long get(IMPLICITDT t, int id) {
        int LSZ = getSize(t.l);
        if (LSZ == id) return t.val;
        if (LSZ < id) return get(t.r, id - LSZ - 1);
        return get(t.l, id);
    }

    static IMPLICITDT split(IMPLICITDT T, int x) {
        IMPLICITDT RES = new IMPLICITDT();
        if (T == null) {
            return RES;
        }
        if (getSize(T.l) > x) {
            IMPLICITDT lsplit = split(T.l, x);
            RES.l = lsplit.l;
            RES.r = T;
            T.l = lsplit.r;
        } else {
            IMPLICITDT rsplit = split(T.r, x - getSize(T.l) - 1);
            RES.r = rsplit.r;
            RES.l = T;
            T.r = rsplit.l;
        }
        recalc(RES);
        recalc(T);
        return RES;
    }

    static IMPLICITDT merge(IMPLICITDT L, IMPLICITDT R) {
        if (L == null) return R;
        if (R == null) return L;
        if (L.y > R.y) return new IMPLICITDT(L.val, L.y, L.l, merge(L.r, R));
        else return new IMPLICITDT(R.val, R.y, merge(L, R.l), R.r);
    }

    static IMPLICITDT insert(IMPLICITDT T, long val, int id) {
        if (T == null) return new IMPLICITDT(val, RANDOMIZER.randomize());
        IMPLICITDT _T = split(T, id);
        IMPLICITDT _TR = new IMPLICITDT(val, RANDOMIZER.randomize());
        IMPLICITDT NEWTREAP = merge(_T.l, _TR);
        IMPLICITDT TREAP = merge(NEWTREAP, _T.r);
        recalc(TREAP);
        return TREAP;
    }
}

class stSUM {
    int t[];
    int a[];

    stSUM(int a[]) {
        this.a = a;
        t = new int[a.length * 4];
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = a[l];
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = t[v * 2] + t[v * 2 + 1];
        }
    }

    void upd(int v, int l, int r, int pos, int x) {
        if (l == r) t[v] = x;
        else {
            int m = (l + r) >> 1;
            if (pos <= m) upd(v * 2, l, m, pos, x);
            else upd(v * 2 + 1, m + 1, r, pos, x);
            t[v] = t[v * 2] + t[v * 2 + 1];
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return t[v];
        if (l > qr || ql > r) return 0;
        int m = (l + r) >> 1;
        return query(v * 2, l, m, ql, qr) + query(v * 2 + 1, m + 1, r, ql, qr);
    }
}

class stMIN {
    int t[];
    int a[];

    stMIN(int a[]) {
        this.a = a;
        t = new int[a.length * 4];
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = a[l];
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = min(t[v * 2], t[v * 2 + 1]);
        }
    }

    void upd(int v, int l, int r, int pos, int x) {
        if (l == r) t[v] = x;
        else {
            int m = (l + r) >> 1;
            if (pos <= m) upd(v * 2, l, m, pos, x);
            else upd(v * 2 + 1, m + 1, r, pos, x);
            t[v] = min(t[v * 2], t[v * 2 + 1]);
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return t[v];
        if (l > qr || ql > r) return Integer.MAX_VALUE;
        int m = (l + r) >> 1;
        return min(query(v * 2, l, m, ql, qr), query(v * 2 + 1, m + 1, r, ql, qr));
    }
}

class DT {
    long val;
    int x, y;
    int sz;
    DT l, r;

    DT() {
        recalc(this);
    }

    DT(int x, int y, long val) {
        this.x = x;
        this.y = y;
        this.val = val;
        recalc(this);
    }

    DT(int x, int y, DT l, DT r, long val) {
        this.x = x;
        this.y = y;
        this.l = l;
        this.r = r;
        this.val = val;
        recalc(this);
    }

    static DT split(DT t, int x) {
        DT res = new DT();
        if (t == null) {
            res.l = null;
            res.r = null;
            return res;
        }
        if (x < t.x) {
            DT lsplit = split(t.l, x);
            res.l = lsplit.l;
            res.r = t;
            t.l = lsplit.r;
        } else {
            DT rsplit = split(t.r, x);
            res.r = rsplit.r;
            res.l = t;
            t.r = rsplit.l;
        }
        recalc(t);
        recalc(res);
        return res;
    }

    static DT merge(DT t1, DT t2) {
        if (t1 == null || t2 == null)
            return t1 == null ? t2 : t1;
        if (t1.y < t2.y) {
            t1.r = merge(t1.r, t2);
            recalc(t1);
            return t1;
        } else {
            t2.l = merge(t1, t2.l);
            recalc(t2);
            return t2;
        }
    }

    static void recalc(DT t) {
        if (t == null) return;
        int lsz = t.l == null ? 0 : t.l.sz;
        int rsz = t.r == null ? 0 : t.r.sz;
        t.sz = lsz + rsz + 1;
    }

    static DT insert(DT t, int x, long val) {
        try {
            if (t == null) {
                DT ret = new DT(x, RANDOMIZER.randomize(), val);
                recalc(ret);
                return ret;
            }
            DT split = split(t, x);
            DT prelast = merge(split.l, new DT(x, RANDOMIZER.randomize(), val));
            DT newtreap = merge(prelast, split.r);
            recalc(newtreap);
            return newtreap;
        } catch (Exception e) {
            System.exit(0);
            return new DT();
        }
    }

    static long find_kth(DT t, int k) {
        if (t.l == null && k == 1)
            return t.val;
        if (t.l != null && t.l.sz == k - 1)
            return t.val;
        if (t.l != null && t.l.sz >= k)
            return find_kth(t.l, k);
        else
            return find_kth(t.r, k - (t.l == null ? 0 : t.l.sz) - 1);
    }

}

class FT {
    private int[] a;
    private long[] t;

    FT(int[] a) {
        this.a = a;
        t = new long[a.length];
    }

    void inc(int i, int delta) {
        for (; i < a.length; i = (i | (i + 1)))
            t[i] += delta;
    }

    long sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }

    private long sum(int r) {
        long sum = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) {
            sum += t[r];
        }
        return sum;
    }
}

class LAZY_ST {
    long min[], sum[], set[];
    int last;
    long not_set = Long.MAX_VALUE;

    LAZY_ST(long a[]) {
        int n = a.length;
        last = n - 1;
        min = new long[4 * n];
        sum = new long[4 * n];
        set = new long[4 * n];
        for (int i = 0; i < 4 * n; i++) {
            set[i] = not_set;
        }
        build(0, 0, last, a);
    }

    void build(int v, int l, int r, long a[]) {
        if (l == r) {
            min[v] = a[l];
            return;
        }
        int m = ((l + r) >> 1);
        build(v * 2 + 1, l, m, a);
        build(v * 2 + 2, m + 1, r, a);
        min[v] = Math.min(min[v * 2 + 1], min[v * 2 + 2]);
    }

    void push(int v) {
        if (set[v] != not_set) {
            min[v] = set[v];
            sum[v * 2 + 1] = sum[v * 2 + 2] = 0;
            set[v * 2 + 1] = set[v * 2 + 2] = set[v];
            set[v] = not_set;
        }

        min[v] += sum[v];
        sum[v * 2 + 1] += sum[v];
        sum[v * 2 + 2] += sum[v];
        sum[v] = 0;
    }

    void upd(int v) {
        min[v] = Math.min(get_el(v * 2 + 1), get_el(v * 2 + 2));
    }

    long get_el(int v) {
        return (set[v] == not_set ? min[v] : set[v]) + sum[v];
    }

    void set(int l, int r, long x) {
        set(0, 0, last, l, r, x);
    }

    void set(int v, int l, int r, int left, int right, long x) {
        if (l > right || r < left) return;
        if (l >= left && r <= right) {
            sum[v] = 0;
            set[v] = x;
            return;
        }
        push(v);
        int m = ((l + r) >> 1);

        set(v * 2 + 1, l, m, left, right, x);
        set(v * 2 + 2, m + 1, r, left, right, x);

        upd(v);
    }

    void add(int l, int r, long x) {
        add(0, 0, last, l, r, x);
    }

    void add(int v, int l, int r, int left, int right, long x) {
        if (l > right || r < left) return;
        if (l >= left && r <= right) {
            sum[v] += x;
            return;
        }
        push(v);
        int m = ((l + r) >> 1);

        add(v * 2 + 1, l, m, left, right, x);
        add(v * 2 + 2, m + 1, r, left, right, x);

        upd(v);
    }

    long get(int l, int r) {
        return get(0, 0, last, l, r);
    }

    long get(int v, int l, int r, int left, int right) {
        if (l > right || r < left) return (long) 1e17;

        if (l >= left && r <= right) {
            return get_el(v);
        }
        push(v);
        int m = ((l + r) >> 1);

        long ans = Math.min(get(v * 2 + 1, l, m, left, right), get(v * 2 + 2, m + 1, r, left, right));
        upd(v);
        return ans;
    }

}

class multiset {
    TreeMap<Long, Integer> t;

    void insert(long val) {
        t.put(val, t.getOrDefault(val, 0) + 1);
    }

    void erase(long val) {
        int nw = t.getOrDefault(val, 1);
        if (nw == 1) t.remove(val);
        else t.put(val, nw - 1);
    }

    long ceiling(long val) {
        return t.ceilingKey(val);
    }

    long floor(long val) {
        return t.floorKey(val);
    }

    long higher(long val) {
        return t.higherKey(val);
    }

    long lower(long val) {
        return t.lowerKey(val);
    }

    int count(long val) {
        return t.getOrDefault(val, 0);
    }
}

class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    FastScanner(File f) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(f));
    }

    FastScanner(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

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

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

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

class tree {
    ArrayList<Integer> g[];
    int n;
    ArrayList<Integer> order;
    int first[];
    int h[];
    int t[];
    int rt;

    tree(ArrayList<Integer> g[]) {
        this.g = g;
        this.n = g.length;
        order = new ArrayList<>();
        first = new int[n];
        fill(first, -1);
        h = new int[n];
        rt = 0;
        dfs(rt, -1);
        prepare();
    }

    void dfs(int v, int p) {
        if (first[v] == -1) first[v] = order.size();
        order.add(v);
        for (int to : g[v]) {
            if (to == p) continue;
            h[to] = h[v] + 1;
            dfs(to, v);
            order.add(v);
        }
    }

    void prepare() {
        t = new int[order.size() * 4];
        build(1, 0, order.size() - 1);
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = order.get(l);
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = h[t[v * 2]] < h[t[v * 2 + 1]] ? t[v * 2] : t[v * 2 + 1];
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (l > qr || ql > r) return Integer.MAX_VALUE;
        if (ql <= l && r <= qr) return t[v];
        int m = (l + r) >> 1;
        int v1 = query(v * 2, l, m, ql, qr);
        int v2 = query(v * 2 + 1, m + 1, r, ql, qr);
        if (v1 == Integer.MAX_VALUE) return v2;
        if (v2 == Integer.MAX_VALUE) return v1;
        return h[v1] < h[v2] ? v1 : v2;
    }

    int lca(int a, int b) {
        int l = first[a];
        int r = first[b];
        return query(1, 0, order.size() - 1, min(l, r), max(l, r));
    }
}


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

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Main {
    static long mod = 998244353;

    static long pow(long a, int n) {
        if (n == 0) return 1;
        if ((n & 1) == 0) return (pow(a, n / 2) % mod * pow(a, n / 2) % mod) % mod;
        return a % mod * pow(a, n - 1) % mod;
    }

    public static void main(String[] args) throws IOException {
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        int k = in.nextInt();
//        if(n == 5 && k == 5){
//            out.println(1000);
//            out.close();
//            return;
//        }
        array a = new array(n);
        a.scan(in);
        long h[] = a.a;
        long _h[] = a.right_shift(1);
        int eq = 0;
        for (int i = 0; i < n; i++) {
            if (h[i] == _h[i]) ++eq;
        }
        long f = max(1, pow(k, eq));
        int N = n - eq;
        long c[][] = new long[N + 1][N + 1];

        for (int i = 1; i < N + 1; i++) {
            c[i][1] = i;
        }
        for (int nn = 2; nn < N + 1; nn++) {
            for (int kk = 2; kk < N + 1; kk++) {
                c[nn][kk] = c[nn - 1][kk - 1] + c[nn - 1][kk];
                c[nn][kk] %= mod;
            }
        }
        for (int i = 0; i < N + 1; i++) {
            for (int j = 0; j < N + 1; j++) {
                if (c[i][j] == 0) c[i][j] = 1;
            }
        }
        long ans = 0;
        for (int i = 0; i <= N; i++) {
            long q = c[N][i] * pow(k - 2,i);
            if(i == 0)q = 1;
            int lft = N - i;
            long s = 0;
            for (int j = 0; j <= lft; j++) {
                if (j >= lft - j) break;
                s += c[lft][lft - j];
                s%=mod;
            }
            ans += (q%mod * s%mod);
            ans%=mod;
        }
        out.println(ans * f % mod);
        out.close();
    }
}

class RANDOMIZER {
    static Random rnd = new Random();

    static int randomize() {
        return rnd.nextInt();
    }
}

class array {
    long a[];

    array(long a[]) {
        this.a = a;
    }

    array(int n) {
        a = new long[n];
    }

    void shuffle() {
        for (int i = 0; i < a.length; i++) {
            int id1 = ((RANDOMIZER.randomize() % a.length) + a.length) % a.length;
            int id2 = ((RANDOMIZER.randomize() % a.length) + a.length) % a.length;
            long t = a[id1];
            a[id1] = a[id2];
            a[id2] = t;
        }
    }

    void reverse(int l, int r) {
        for (int i = l; i < l + (r - l + 1) >> 1; i++) {
            long t = a[i];
            a[i] = a[r - i];
            a[r - i] = t;
        }
    }

    long[] right_shift(int shift) {
        long aa[] = new long[a.length];
        for (int i = 0; i < a.length; i++) {
            aa[(i + shift) % a.length] = a[i];
        }
        return aa;
    }

    void add(int l, int r, long val) {
        for (int i = l; i <= r; i++) {
            a[i] += val;
        }
    }

    void print(PrintWriter out) {
        for (int i = 0; i < a.length; i++) {
            out.print(a[i] + " ");
        }
    }

    void copy(long t[]) {
        for (int i = 0; i < a.length; i++) {
            a[i] = t[i];
        }
    }

    void scan(FastScanner in) throws IOException {
        for (int i = 0; i < a.length; i++) {
            a[i] = in.nextLong();
        }
    }

    long getSum() {
        long sum = 0;
        long md = (long) 1e16;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
            sum %= md;
        }
        return sum;
    }

    long getMin() {
        long min = Long.MAX_VALUE;
        for (int i = 0; i < a.length; i++) {
            min = min(min, a[i]);
        }
        return min;
    }

    long getMax() {
        long max = Long.MIN_VALUE;
        for (int i = 0; i < a.length; i++) {
            max = max(max, a[i]);
        }
        return max;
    }

    int ceilingID(long val) {
        int l = 0;
        int r = a.length - 1;
        while (l + 1 != r) {
            int m = (l + r) >> 1;
            if (a[m] >= val) r = m;
            else l = m;
        }
        int pr = l;
        if (pr > 0 && a[pr - 1] >= val) pr--;
        if (a[pr] < val) pr++;
        if (pr < a.length && a[pr] < val) pr++;
        return pr;
    }
}

class dsu {
    int p[];
    int max[];

    dsu(int n) {
        p = new int[n];
        max = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i;
            max[i] = i;
        }
    }

    int get(int a) {
        if (p[a] == a) return a;
        return p[a] = get(p[a]);
    }

    void merge(int a, int b) {
        a = get(a);
        b = get(b);
        if (a != b) {
            p[a] = b;
            max[b] = max(max[a], max[b]);
        }
    }
}

class vertex {
    int next[];
}

class trie {
    vertex t[];
    int sz = 1;
    int k;

    trie(int k) {
        this.k = k;
        t = new vertex[300000];
        for (int i = 0; i < t.length; i++) {
            t[i] = new vertex();
            t[i].next = new int[k];
            for (int j = 0; j < k; j++) {
                t[i].next[j] = -1;
            }
        }
    }

    void add(String s, int id) {
        int v = 0;
        for (int i = 0; i < s.length(); i++) {
            char rc = (char) (s.charAt(i) - 'a');
            if (t[v].next[rc] == -1) {
                t[v].next[rc] = sz++;
            }
            v = t[v].next[rc];
        }
    }
}

class StringHelper {
    char[] s;
    long hash[];
    long px[];
    long mod = (int) 1e9 + 7;
    long x = 255;
    int n;

    public StringHelper(String s) {
        this.s = s.toCharArray();
        n = s.length();
    }

    int[] pi() {
        int pi[] = new int[n];
        for (int i = 1; i < n; i++) {
            int j = pi[i - 1];
            while (j > 0 && s[i] != s[j]) j = pi[j - 1];
            pi[i] = s[i] == s[j] ? j + 1 : j;
        }
        return pi;
    }

    void calcHash() {
        hash = new long[n + 1];
        px = new long[n + 3];
        px[0] = 1;
        for (int i = 1; i < n + 3; i++) {
            px[i] = px[i - 1] * x % mod;
        }
        for (int i = 1; i < n + 1; i++) {
            hash[i] = (hash[i - 1] * x % mod + s[i - 1] + mod) % mod;
        }
    }

    long getHash(int l, int r) {
        return (hash[r + 1] - hash[l] * px[r - l + 1] % mod + mod) % mod;
    }
}

class IMPLICITDT {
    long val;
    int y;
    int sz;
    IMPLICITDT l, r;

    static int getSize(IMPLICITDT t) {
        return t == null ? 0 : t.sz;
    }

    private static void recalc(IMPLICITDT t) {
        if (t == null) return;
        int LSZ = t.l == null ? 0 : t.l.sz;
        int RSZ = t.r == null ? 0 : t.r.sz;
        t.sz = LSZ + RSZ + 1;
    }

    IMPLICITDT() {
    }

    IMPLICITDT(long cost, int y, IMPLICITDT l, IMPLICITDT r) {
        this.val = cost;
        this.y = y;
        this.l = l;
        this.r = r;
        recalc(this);
    }

    IMPLICITDT(long cost, int y) {
        this.val = cost;
        this.y = y;
        recalc(this);
    }

    static long get(IMPLICITDT t, int id) {
        int LSZ = getSize(t.l);
        if (LSZ == id) return t.val;
        if (LSZ < id) return get(t.r, id - LSZ - 1);
        return get(t.l, id);
    }

    static IMPLICITDT split(IMPLICITDT T, int x) {
        IMPLICITDT RES = new IMPLICITDT();
        if (T == null) {
            return RES;
        }
        if (getSize(T.l) > x) {
            IMPLICITDT lsplit = split(T.l, x);
            RES.l = lsplit.l;
            RES.r = T;
            T.l = lsplit.r;
        } else {
            IMPLICITDT rsplit = split(T.r, x - getSize(T.l) - 1);
            RES.r = rsplit.r;
            RES.l = T;
            T.r = rsplit.l;
        }
        recalc(RES);
        recalc(T);
        return RES;
    }

    static IMPLICITDT merge(IMPLICITDT L, IMPLICITDT R) {
        if (L == null) return R;
        if (R == null) return L;
        if (L.y > R.y) return new IMPLICITDT(L.val, L.y, L.l, merge(L.r, R));
        else return new IMPLICITDT(R.val, R.y, merge(L, R.l), R.r);
    }

    static IMPLICITDT insert(IMPLICITDT T, long val, int id) {
        if (T == null) return new IMPLICITDT(val, RANDOMIZER.randomize());
        IMPLICITDT _T = split(T, id);
        IMPLICITDT _TR = new IMPLICITDT(val, RANDOMIZER.randomize());
        IMPLICITDT NEWTREAP = merge(_T.l, _TR);
        IMPLICITDT TREAP = merge(NEWTREAP, _T.r);
        recalc(TREAP);
        return TREAP;
    }
}

class stSUM {
    int t[];
    int a[];

    stSUM(int a[]) {
        this.a = a;
        t = new int[a.length * 4];
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = a[l];
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = t[v * 2] + t[v * 2 + 1];
        }
    }

    void upd(int v, int l, int r, int pos, int x) {
        if (l == r) t[v] = x;
        else {
            int m = (l + r) >> 1;
            if (pos <= m) upd(v * 2, l, m, pos, x);
            else upd(v * 2 + 1, m + 1, r, pos, x);
            t[v] = t[v * 2] + t[v * 2 + 1];
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return t[v];
        if (l > qr || ql > r) return 0;
        int m = (l + r) >> 1;
        return query(v * 2, l, m, ql, qr) + query(v * 2 + 1, m + 1, r, ql, qr);
    }
}

class stMIN {
    int t[];
    int a[];

    stMIN(int a[]) {
        this.a = a;
        t = new int[a.length * 4];
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = a[l];
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = min(t[v * 2], t[v * 2 + 1]);
        }
    }

    void upd(int v, int l, int r, int pos, int x) {
        if (l == r) t[v] = x;
        else {
            int m = (l + r) >> 1;
            if (pos <= m) upd(v * 2, l, m, pos, x);
            else upd(v * 2 + 1, m + 1, r, pos, x);
            t[v] = min(t[v * 2], t[v * 2 + 1]);
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return t[v];
        if (l > qr || ql > r) return Integer.MAX_VALUE;
        int m = (l + r) >> 1;
        return min(query(v * 2, l, m, ql, qr), query(v * 2 + 1, m + 1, r, ql, qr));
    }
}

class DT {
    long val;
    int x, y;
    int sz;
    DT l, r;

    DT() {
        recalc(this);
    }

    DT(int x, int y, long val) {
        this.x = x;
        this.y = y;
        this.val = val;
        recalc(this);
    }

    DT(int x, int y, DT l, DT r, long val) {
        this.x = x;
        this.y = y;
        this.l = l;
        this.r = r;
        this.val = val;
        recalc(this);
    }

    static DT split(DT t, int x) {
        DT res = new DT();
        if (t == null) {
            res.l = null;
            res.r = null;
            return res;
        }
        if (x < t.x) {
            DT lsplit = split(t.l, x);
            res.l = lsplit.l;
            res.r = t;
            t.l = lsplit.r;
        } else {
            DT rsplit = split(t.r, x);
            res.r = rsplit.r;
            res.l = t;
            t.r = rsplit.l;
        }
        recalc(t);
        recalc(res);
        return res;
    }

    static DT merge(DT t1, DT t2) {
        if (t1 == null || t2 == null)
            return t1 == null ? t2 : t1;
        if (t1.y < t2.y) {
            t1.r = merge(t1.r, t2);
            recalc(t1);
            return t1;
        } else {
            t2.l = merge(t1, t2.l);
            recalc(t2);
            return t2;
        }
    }

    static void recalc(DT t) {
        if (t == null) return;
        int lsz = t.l == null ? 0 : t.l.sz;
        int rsz = t.r == null ? 0 : t.r.sz;
        t.sz = lsz + rsz + 1;
    }

    static DT insert(DT t, int x, long val) {
        try {
            if (t == null) {
                DT ret = new DT(x, RANDOMIZER.randomize(), val);
                recalc(ret);
                return ret;
            }
            DT split = split(t, x);
            DT prelast = merge(split.l, new DT(x, RANDOMIZER.randomize(), val));
            DT newtreap = merge(prelast, split.r);
            recalc(newtreap);
            return newtreap;
        } catch (Exception e) {
            System.exit(0);
            return new DT();
        }
    }

    static long find_kth(DT t, int k) {
        if (t.l == null && k == 1)
            return t.val;
        if (t.l != null && t.l.sz == k - 1)
            return t.val;
        if (t.l != null && t.l.sz >= k)
            return find_kth(t.l, k);
        else
            return find_kth(t.r, k - (t.l == null ? 0 : t.l.sz) - 1);
    }

}

class FT {
    private int[] a;
    private long[] t;

    FT(int[] a) {
        this.a = a;
        t = new long[a.length];
    }

    void inc(int i, int delta) {
        for (; i < a.length; i = (i | (i + 1)))
            t[i] += delta;
    }

    long sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }

    private long sum(int r) {
        long sum = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) {
            sum += t[r];
        }
        return sum;
    }
}

class LAZY_ST {
    long min[], sum[], set[];
    int last;
    long not_set = Long.MAX_VALUE;

    LAZY_ST(long a[]) {
        int n = a.length;
        last = n - 1;
        min = new long[4 * n];
        sum = new long[4 * n];
        set = new long[4 * n];
        for (int i = 0; i < 4 * n; i++) {
            set[i] = not_set;
        }
        build(0, 0, last, a);
    }

    void build(int v, int l, int r, long a[]) {
        if (l == r) {
            min[v] = a[l];
            return;
        }
        int m = ((l + r) >> 1);
        build(v * 2 + 1, l, m, a);
        build(v * 2 + 2, m + 1, r, a);
        min[v] = Math.min(min[v * 2 + 1], min[v * 2 + 2]);
    }

    void push(int v) {
        if (set[v] != not_set) {
            min[v] = set[v];
            sum[v * 2 + 1] = sum[v * 2 + 2] = 0;
            set[v * 2 + 1] = set[v * 2 + 2] = set[v];
            set[v] = not_set;
        }

        min[v] += sum[v];
        sum[v * 2 + 1] += sum[v];
        sum[v * 2 + 2] += sum[v];
        sum[v] = 0;
    }

    void upd(int v) {
        min[v] = Math.min(get_el(v * 2 + 1), get_el(v * 2 + 2));
    }

    long get_el(int v) {
        return (set[v] == not_set ? min[v] : set[v]) + sum[v];
    }

    void set(int l, int r, long x) {
        set(0, 0, last, l, r, x);
    }

    void set(int v, int l, int r, int left, int right, long x) {
        if (l > right || r < left) return;
        if (l >= left && r <= right) {
            sum[v] = 0;
            set[v] = x;
            return;
        }
        push(v);
        int m = ((l + r) >> 1);

        set(v * 2 + 1, l, m, left, right, x);
        set(v * 2 + 2, m + 1, r, left, right, x);

        upd(v);
    }

    void add(int l, int r, long x) {
        add(0, 0, last, l, r, x);
    }

    void add(int v, int l, int r, int left, int right, long x) {
        if (l > right || r < left) return;
        if (l >= left && r <= right) {
            sum[v] += x;
            return;
        }
        push(v);
        int m = ((l + r) >> 1);

        add(v * 2 + 1, l, m, left, right, x);
        add(v * 2 + 2, m + 1, r, left, right, x);

        upd(v);
    }

    long get(int l, int r) {
        return get(0, 0, last, l, r);
    }

    long get(int v, int l, int r, int left, int right) {
        if (l > right || r < left) return (long) 1e17;

        if (l >= left && r <= right) {
            return get_el(v);
        }
        push(v);
        int m = ((l + r) >> 1);

        long ans = Math.min(get(v * 2 + 1, l, m, left, right), get(v * 2 + 2, m + 1, r, left, right));
        upd(v);
        return ans;
    }

}

class multiset {
    TreeMap<Long, Integer> t;

    void insert(long val) {
        t.put(val, t.getOrDefault(val, 0) + 1);
    }

    void erase(long val) {
        int nw = t.getOrDefault(val, 1);
        if (nw == 1) t.remove(val);
        else t.put(val, nw - 1);
    }

    long ceiling(long val) {
        return t.ceilingKey(val);
    }

    long floor(long val) {
        return t.floorKey(val);
    }

    long higher(long val) {
        return t.higherKey(val);
    }

    long lower(long val) {
        return t.lowerKey(val);
    }

    int count(long val) {
        return t.getOrDefault(val, 0);
    }
}

class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    FastScanner(File f) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(f));
    }

    FastScanner(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

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

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

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

class tree {
    ArrayList<Integer> g[];
    int n;
    ArrayList<Integer> order;
    int first[];
    int h[];
    int t[];
    int rt;

    tree(ArrayList<Integer> g[]) {
        this.g = g;
        this.n = g.length;
        order = new ArrayList<>();
        first = new int[n];
        fill(first, -1);
        h = new int[n];
        rt = 0;
        dfs(rt, -1);
        prepare();
    }

    void dfs(int v, int p) {
        if (first[v] == -1) first[v] = order.size();
        order.add(v);
        for (int to : g[v]) {
            if (to == p) continue;
            h[to] = h[v] + 1;
            dfs(to, v);
            order.add(v);
        }
    }

    void prepare() {
        t = new int[order.size() * 4];
        build(1, 0, order.size() - 1);
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = order.get(l);
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = h[t[v * 2]] < h[t[v * 2 + 1]] ? t[v * 2] : t[v * 2 + 1];
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (l > qr || ql > r) return Integer.MAX_VALUE;
        if (ql <= l && r <= qr) return t[v];
        int m = (l + r) >> 1;
        int v1 = query(v * 2, l, m, ql, qr);
        int v2 = query(v * 2 + 1, m + 1, r, ql, qr);
        if (v1 == Integer.MAX_VALUE) return v2;
        if (v2 == Integer.MAX_VALUE) return v1;
        return h[v1] < h[v2] ? v1 : v2;
    }

    int lca(int a, int b) {
        int l = first[a];
        int r = first[b];
        return query(1, 0, order.size() - 1, min(l, r), max(l, r));
    }
}


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

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class Solver {
    static long cost[];
    static ArrayList<Integer> g[];
    static long dp[];
    static int k;
    static TreeSet<Integer>sons[][];
    static void find_son(int v, int p){
        for(int to : g[v]){
            if(to == p)continue;
            sons[v][1].add(to);
            find_son(to,v);
            for (int i = 1; i < g.length; i++) {
                sons[v][i].addAll(sons[to][i-1]);
            }
        }
    }
    static void dfs(int v, int p){
        for(int to )
    }
    public static void main(String[] args) throws IOException {
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        k = in.nextInt();
        cost = new long[n];
        for (int i = 0; i < n; i++) {
            cost[i] = in.nextLong();
        }
        sons = new TreeSet[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                sons[i][j] = new TreeSet<>();
            }
        }
        g = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            g[i] = new ArrayList<>();
        }
        for (int i = 0; i < n - 1; i++) {
            int v = in.nextInt() - 1;
            int u = in.nextInt() - 1;
            g[v].add(u);
            g[u].add(v);
         }
        dp = new long[n];
        find_son(0,-1);
    }
}

class RANDOMIZER {
    static Random rnd = new Random();

    static int randomize() {
        return rnd.nextInt();
    }
}

class array {
    long a[];

    array(long a[]) {
        this.a = a;
    }

    array(int n) {
        a = new long[n];
    }

    void shuffle() {
        for (int i = 0; i < a.length; i++) {
            int id1 = ((RANDOMIZER.randomize() % a.length) + a.length) % a.length;
            int id2 = ((RANDOMIZER.randomize() % a.length) + a.length) % a.length;
            long t = a[id1];
            a[id1] = a[id2];
            a[id2] = t;
        }
    }

    void reverse(int l, int r) {
        for (int i = l; i < l + (r - l + 1) >> 1; i++) {
            long t = a[i];
            a[i] = a[r - i];
            a[r - i] = t;
        }
    }

    long[] right_shift(int shift) {
        long aa[] = new long[a.length];
        for (int i = 0; i < a.length; i++) {
            aa[(i + shift) % a.length] = a[i];
        }
        return aa;
    }

    void add(int l, int r, long val) {
        for (int i = l; i <= r; i++) {
            a[i] += val;
        }
    }

    void print(PrintWriter out) {
        for (int i = 0; i < a.length; i++) {
            out.print(a[i] + " ");
        }
    }

    void copy(long t[]) {
        for (int i = 0; i < a.length; i++) {
            a[i] = t[i];
        }
    }

    void scan(FastScanner in) throws IOException {
        for (int i = 0; i < a.length; i++) {
            a[i] = in.nextLong();
        }
    }

    long getSum() {
        long sum = 0;
        long md = (long) 1e16;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
            sum %= md;
        }
        return sum;
    }

    long getMin() {
        long min = Long.MAX_VALUE;
        for (int i = 0; i < a.length; i++) {
            min = min(min, a[i]);
        }
        return min;
    }

    long getMax() {
        long max = Long.MIN_VALUE;
        for (int i = 0; i < a.length; i++) {
            max = max(max, a[i]);
        }
        return max;
    }

    int ceilingID(long val) {
        int l = 0;
        int r = a.length - 1;
        while (l + 1 != r) {
            int m = (l + r) >> 1;
            if (a[m] >= val) r = m;
            else l = m;
        }
        int pr = l;
        if (pr > 0 && a[pr - 1] >= val) pr--;
        if (a[pr] < val) pr++;
        if (pr < a.length && a[pr] < val) pr++;
        return pr;
    }
}

class dsu {
    int p[];
    int max[];

    dsu(int n) {
        p = new int[n];
        max = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i;
            max[i] = i;
        }
    }

    int get(int a) {
        if (p[a] == a) return a;
        return p[a] = get(p[a]);
    }

    void merge(int a, int b) {
        a = get(a);
        b = get(b);
        if (a != b) {
            p[a] = b;
            max[b] = max(max[a], max[b]);
        }
    }
}

class vertex {
    int next[];
}

class trie {
    vertex t[];
    int sz = 1;
    int k;

    trie(int k) {
        this.k = k;
        t = new vertex[300000];
        for (int i = 0; i < t.length; i++) {
            t[i] = new vertex();
            t[i].next = new int[k];
            for (int j = 0; j < k; j++) {
                t[i].next[j] = -1;
            }
        }
    }

    void add(String s, int id) {
        int v = 0;
        for (int i = 0; i < s.length(); i++) {
            char rc = (char) (s.charAt(i) - 'a');
            if (t[v].next[rc] == -1) {
                t[v].next[rc] = sz++;
            }
            v = t[v].next[rc];
        }
    }
}

class StringHelper {
    char[] s;
    long hash[];
    long px[];
    long mod = (int) 1e9 + 7;
    long x = 255;
    int n;

    public StringHelper(String s) {
        this.s = s.toCharArray();
        n = s.length();
    }

    int[] pi() {
        int pi[] = new int[n];
        for (int i = 1; i < n; i++) {
            int j = pi[i - 1];
            while (j > 0 && s[i] != s[j]) j = pi[j - 1];
            pi[i] = s[i] == s[j] ? j + 1 : j;
        }
        return pi;
    }

    void calcHash() {
        hash = new long[n + 1];
        px = new long[n + 3];
        px[0] = 1;
        for (int i = 1; i < n + 3; i++) {
            px[i] = px[i - 1] * x % mod;
        }
        for (int i = 1; i < n + 1; i++) {
            hash[i] = (hash[i - 1] * x % mod + s[i - 1] + mod) % mod;
        }
    }

    long getHash(int l, int r) {
        return (hash[r + 1] - hash[l] * px[r - l + 1] % mod + mod) % mod;
    }
}

class IMPLICITDT {
    long val;
    int y;
    int sz;
    IMPLICITDT l, r;

    static int getSize(IMPLICITDT t) {
        return t == null ? 0 : t.sz;
    }

    private static void recalc(IMPLICITDT t) {
        if (t == null) return;
        int LSZ = t.l == null ? 0 : t.l.sz;
        int RSZ = t.r == null ? 0 : t.r.sz;
        t.sz = LSZ + RSZ + 1;
    }

    IMPLICITDT() {
    }

    IMPLICITDT(long cost, int y, IMPLICITDT l, IMPLICITDT r) {
        this.val = cost;
        this.y = y;
        this.l = l;
        this.r = r;
        recalc(this);
    }

    IMPLICITDT(long cost, int y) {
        this.val = cost;
        this.y = y;
        recalc(this);
    }

    static long get(IMPLICITDT t, int id) {
        int LSZ = getSize(t.l);
        if (LSZ == id) return t.val;
        if (LSZ < id) return get(t.r, id - LSZ - 1);
        return get(t.l, id);
    }

    static IMPLICITDT split(IMPLICITDT T, int x) {
        IMPLICITDT RES = new IMPLICITDT();
        if (T == null) {
            return RES;
        }
        if (getSize(T.l) > x) {
            IMPLICITDT lsplit = split(T.l, x);
            RES.l = lsplit.l;
            RES.r = T;
            T.l = lsplit.r;
        } else {
            IMPLICITDT rsplit = split(T.r, x - getSize(T.l) - 1);
            RES.r = rsplit.r;
            RES.l = T;
            T.r = rsplit.l;
        }
        recalc(RES);
        recalc(T);
        return RES;
    }

    static IMPLICITDT merge(IMPLICITDT L, IMPLICITDT R) {
        if (L == null) return R;
        if (R == null) return L;
        if (L.y > R.y) return new IMPLICITDT(L.val, L.y, L.l, merge(L.r, R));
        else return new IMPLICITDT(R.val, R.y, merge(L, R.l), R.r);
    }

    static IMPLICITDT insert(IMPLICITDT T, long val, int id) {
        if (T == null) return new IMPLICITDT(val, RANDOMIZER.randomize());
        IMPLICITDT _T = split(T, id);
        IMPLICITDT _TR = new IMPLICITDT(val, RANDOMIZER.randomize());
        IMPLICITDT NEWTREAP = merge(_T.l, _TR);
        IMPLICITDT TREAP = merge(NEWTREAP, _T.r);
        recalc(TREAP);
        return TREAP;
    }
}

class stSUM {
    int t[];
    int a[];

    stSUM(int a[]) {
        this.a = a;
        t = new int[a.length * 4];
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = a[l];
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = t[v * 2] + t[v * 2 + 1];
        }
    }

    void upd(int v, int l, int r, int pos, int x) {
        if (l == r) t[v] = x;
        else {
            int m = (l + r) >> 1;
            if (pos <= m) upd(v * 2, l, m, pos, x);
            else upd(v * 2 + 1, m + 1, r, pos, x);
            t[v] = t[v * 2] + t[v * 2 + 1];
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return t[v];
        if (l > qr || ql > r) return 0;
        int m = (l + r) >> 1;
        return query(v * 2, l, m, ql, qr) + query(v * 2 + 1, m + 1, r, ql, qr);
    }
}

class stMIN {
    int t[];
    int a[];

    stMIN(int a[]) {
        this.a = a;
        t = new int[a.length * 4];
    }

    void build(int v, int l, int r) {
        if (l == r) t[v] = a[l];
        else {
            int m = (l + r) >> 1;
            build(v * 2, l, m);
            build(v * 2 + 1, m + 1, r);
            t[v] = min(t[v * 2], t[v * 2 + 1]);
        }
    }

    void upd(int v, int l, int r, int pos, int x) {
        if (l == r) t[v] = x;
        else {
            int m = (l + r) >> 1;
            if (pos <= m) upd(v * 2, l, m, pos, x);
            else upd(v * 2 + 1, m + 1, r, pos, x);
            t[v] = min(t[v * 2], t[v * 2 + 1]);
        }
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return t[v];
        if (l > qr || ql > r) return Integer.MAX_VALUE;
        int m = (l + r) >> 1;
        return min(query(v * 2, l, m, ql, qr), query(v * 2 + 1, m + 1, r, ql, qr));
    }
}

class DT {
    long val;
    int x, y;
    int sz;
    DT l, r;

    DT() {
        recalc(this);
    }

    DT(int x, int y, long val) {
        this.x = x;
        this.y = y;
        this.val = val;
        recalc(this);
    }

    DT(int x, int y, DT l, DT r, long val) {
        this.x = x;
        this.y = y;
        this.l = l;
        this.r = r;
        this.val = val;
        recalc(this);
    }

    static DT split(DT t, int x) {
        DT res = new DT();
        if (t == null) {
            res.l = null;
            res.r = null;
            return res;
        }
        if (x < t.x) {
            DT lsplit = split(t.l, x);
            res.l = lsplit.l;
            res.r = t;
            t.l = lsplit.r;
        } else {
            DT rsplit = split(t.r, x);
            res.r = rsplit.r;
            res.l = t;
            t.r = rsplit.l;
        }
        recalc(t);
        recalc(res);
        return res;
    }

    static DT merge(DT t1, DT t2) {
        if (t1 == null || t2 == null)
            return t1 == null ? t2 : t1;
        if (t1.y < t2.y) {
            t1.r = merge(t1.r, t2);
            recalc(t1);
            return t1;
        } else {
            t2.l = merge(t1, t2.l);
            recalc(t2);
            return t2;
        }
    }

    static void recalc(DT t) {
        if (t == null) return;
        int lsz = t.l == null ? 0 : t.l.sz;
        int rsz = t.r == null ? 0 : t.r.sz;
        t.sz = lsz + rsz + 1;
    }

    static DT insert(DT t, int x, long val) {
        try {
            if (t == null) {
                DT ret = new DT(x, RANDOMIZER.randomize(), val);
                recalc(ret);
                return ret;
            }
            DT split = split(t, x);
            DT prelast = merge(split.l, new DT(x, RANDOMIZER.randomize(), val));
            DT newtreap = merge(prelast, split.r);
            recalc(newtreap);
            return newtreap;
        } catch (Exception e) {
            System.exit(0);
            return new DT();
        }
    }

    static long find_kth(DT t, int k) {
        if (t.l == null && k == 1)
            return t.val;
        if (t.l != null && t.l.sz == k - 1)
            return t.val;
        if (t.l != null && t.l.sz >= k)
            return find_kth(t.l, k);
        else
            return find_kth(t.r, k - (t.l == null ? 0 : t.l.sz) - 1);
    }

}

class FT {
    private int[] a;
    private long[] t;

    FT(int[] a) {
        this.a = a;
        t = new long[a.length];
    }

    void inc(int i, int delta) {
        for (; i < a.length; i = (i | (i + 1)))
            t[i] += delta;
    }

    long sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }

    private long sum(int r) {
        long sum = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) {
            sum += t[r];
        }
        return sum;
    }
}

class LAZY_ST {
    long min[], sum[], set[];
    int last;
    long not_set = Long.MAX_VALUE;

    LAZY_ST(long a[]) {
        int n = a.length;
        last = n - 1;
        min = new long[4 * n];
        sum = new long[4 * n];
        set = new long[4 * n];
        for (int i = 0; i < 4 * n; i++) {
            set[i] = not_set;
        }
        build(0, 0, last, a);
    }

    void build(int v, int l, int r, long a[]) {
        if (l == r) {
            min[v] = a[l];
            return;
        }
        int m = ((l + r) >> 1);
        build(v * 2 + 1, l, m, a);
        build(v * 2 + 2, m + 1, r, a);
        min[v] = Math.min(min[v * 2 + 1], min[v * 2 + 2]);
    }

    void push(int v) {
        if (set[v] != not_set) {
            min[v] = set[v];
            sum[v * 2 + 1] = sum[v * 2 + 2] = 0;
            set[v * 2 + 1] = set[v * 2 + 2] = set[v];
            set[v] = not_set;
        }

        min[v] += sum[v];
        sum[v * 2 + 1] += sum[v];
        sum[v * 2 + 2] += sum[v];
        sum[v] = 0;
    }

    void upd(int v) {
        min[v] = Math.min(get_el(v * 2 + 1), get_el(v * 2 + 2));
    }

    long get_el(int v) {
        return (set[v] == not_set ? min[v] : set[v]) + sum[v];
    }

    void set(int l, int r, long x) {
        set(0, 0, last, l, r, x);
    }

    void set(int v, int l, int r, int left, int right, long x) {
        if (l > right || r < left) return;
        if (l >= left && r <= right) {
            sum[v] = 0;
            set[v] = x;
            return;
        }
        push(v);
        int m = ((l + r) >> 1);

        set(v * 2 + 1, l, m, left, right, x);
        set(v * 2 + 2, m + 1, r, left, right, x);

        upd(v);
    }

    void add(int l, int r, long x) {
        add(0, 0, last, l, r, x);
    }

    void add(int v, int l, int r, int left, int right, long x) {
        if (l > right || r < left) return;
        if (l >= left && r <= right) {
            sum[v] += x;
            return;
        }
        push(v);
        int m = ((l + r) >> 1);

        add(v * 2 + 1, l, m, left, right, x);
        add(v * 2 + 2, m + 1, r, left, right, x);

        upd(v);
    }

    long get(int l, int r) {
        return get(0, 0, last, l, r);
    }

    long get(int v, int l, int r, int left, int right) {
        if (l > right || r < left) return (long) 1e17;

        if (l >= left && r <= right) {
            return get_el(v);
        }
        push(v);
        int m = ((l + r) >> 1);

        long ans = Math.min(get(v * 2 + 1, l, m, left, right), get(v * 2 + 2, m + 1, r, left, right));
        upd(v);
        return ans;
    }

}

class multiset {
    TreeMap<Long, Integer> t;

    void insert(long val) {
        t.put(val, t.getOrDefault(val, 0) + 1);
    }

    void erase(long val) {
        int nw = t.getOrDefault(val, 1);
        if (nw == 1) t.remove(val);
        else t.put(val, nw - 1);
    }

    long ceiling(long val) {
        return t.ceilingKey(val);
    }

    long floor(long val) {
        return t.floorKey(val);
    }

    long higher(long val) {
        return t.higherKey(val);
    }

    long lower(long val) {
        return t.lowerKey(val);
    }

    int count(long val) {
        return t.getOrDefault(val, 0);
    }
}

class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    FastScanner(File f) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(f));
    }

    FastScanner(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

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

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

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

class tree {
    ArrayList<Integer> g[];
    int n;
    ArrayList<Integer> order;
    int first[];
    int h[];
    int t[];
    int rt;
    tree(ArrayList<Integer> g[]) {
        this.g = g;
        this.n = g.length;
        order = new ArrayList<>();
        first = new int[n];
        fill(first, -1);
        h = new int[n];
        rt = 0;
        dfs(rt, -1);
        prepare();
    }

    void dfs(int v, int p) {
        if (first[v] == -1) first[v] = order.size();
        order.add(v);
        for (int to : g[v]) {
            if (to == p) continue;
            h[to] = h[v] + 1;
            dfs(to, v);
            order.add(v);
        }
    }
    void prepare(){
        t = new int[order.size() * 4];
        build(1,0,order.size()-1);
    }
    void build(int v, int l, int r){
        if(l == r)t[v] = order.get(l);
        else{
            int m = (l + r) >> 1;
            build(v*2,l,m);
            build(v*2+1,m+1,r);
            t[v] = h[t[v*2]] < h[t[v*2 + 1]] ? t[v*2] : t[v*2+1];
        }
    }
    int query(int v, int l, int r, int ql, int qr){
        if(l > qr || ql > r)return Integer.MAX_VALUE;
        if(ql <= l && r <= qr)return t[v];
        int m = (l + r ) >> 1;
        int v1 = query(v*2,l,m,ql,qr);
        int v2 = query(v*2+1,m+1,r,ql,qr);
        if(v1 == Integer.MAX_VALUE)return v2;
        if(v2 == Integer.MAX_VALUE)return v1;
        return h[v1] < h[v2] ? v1 : v2;
    }
    int lca(int a, int b){
        int l = first[a];
        int r = first[b];
        return query(1,0,order.size()-1,min(l,r),max(l,r));
    }
}


import java.io.*;
import java.util.*;
import java.math.*;
import static java.lang.Math.*;

public class Main implements Runnable {

	long MOD = 1000000009;
	public void solve() throws IOException {
		int n = nextInt();
		long[] ans = new long[n + 1];
		long[] q = new long[n + 1];
		long[] Q = new long[n + 1];
		q[0] = Q[0] = 1;
		for(int i = 1; i <= n; ++i) {
			q[i] = (2 * (1 + q[i - 1]) + 1) % MOD;
			Q[i] = q[i] * Q[i - 1];
		}
		ans[2] = 2;
		for(int t = 4; t <= n; t += 2) {
			long qq = (Q[(t - 4) / 2]);
			ans[t] = (ans[t - 2] + 4 * qq) % MOD;
		}
		long tmp = ans[n];
		//pw.println(tmp);
		long p = (tmp * tmp + 1) * 2 % MOD;
		pw.println(p);
	}

	static final String filename = "A";
	static final boolean fromConsole = true;

	public void run() {
		try {
			if (!fromConsole) {
				in = new BufferedReader(new FileReader(filename + ".in"));
				pw = new PrintWriter(filename + ".out");
			} else {
				in = new BufferedReader(new InputStreamReader(System.in));
				pw = new PrintWriter(System.out);
			}
			st = new StringTokenizer("");
			long st = System.currentTimeMillis();
			solve();
			//pw.printf("\nWorking time: %d ms\n", System.currentTimeMillis() - st);
			pw.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	private StringTokenizer st;
	private BufferedReader in;
	private PrintWriter pw;

	boolean hasNext() throws IOException {
		while (!st.hasMoreTokens()) {
			String line = in.readLine();
			if (line == null) {
				return false;
			}
			st = new StringTokenizer(line);
		}
		return st.hasMoreTokens();
	}

	String next() throws IOException {
		return hasNext() ? st.nextToken() : null;
	}

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

	BigInteger nextBigInteger() throws IOException {
		return new BigInteger(next());
	}

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

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

	public static void main(String[] args) {
		new Thread(new Main()).start();
	}
}


//package tes7;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class P15 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		int mod = 1000000009;
		long[] dp = new long[n+1];
		if(6 <= n)dp[6] = 5;
		for(int i = 10;i <= n;i+=4){
			dp[i] = ((dp[i-4] + 1) * 2L + 1) % mod;
		}

		long ret = 1;
		for(int i = n;i >= 3;i--){
			if(dp[i-1] == 0){
				ret = ret + 2;
				if(ret >= mod)ret -= mod;
			}else{
				ret = ((ret+1)*dp[i-1]+1) % mod;
			}
		}
		ret = ((ret+1)*(ret+1)+1)%mod;
		out.println(ret*2%mod);
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new P15().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

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

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

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

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

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

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

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

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

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

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

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

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


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

public class e {

	final long MOD = 1000000009;
	int n;

	private void solve() throws Exception {
		n = nextInt();
		long ans = 1;
		long[] val = new long[n + 1];
		val[2] = val[n] = 1;
		long tmp = 0;
		long sum = 1;
		for (int i = 3; i <= n; i += 2){
			val[i - 1] = 1;
			val[i] = sum;
			tmp = ((tmp + 2) * 2) % MOD;
			sum = (sum + tmp) % MOD;
		}
		for (int i = 3; i <= n; ++i){
			val[i] = (val[i] * val[i - 1]) % MOD;
		}
		long res = 0;
		for (int i = 1; i <= n; ++i){
			if (i == n){
				res = (res + val[i]) % MOD;
			}
			else{
				res = (res + val[i] + val[i + 1]) % MOD;
			}
		}
		ans = (ans + res * res) % MOD;
		ans = (ans * 2) % MOD;
		out.print(ans);
	}

	public void run() {
		try {
			solve();
		} catch (Exception e) {
			NOO(e);
		} finally {
			out.close();
		}
	}

	PrintWriter out;
	BufferedReader in;
	StringTokenizer St;

	void NOO(Exception e) {
		e.printStackTrace();
		System.exit(1);
	}

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

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

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

	String nextToken() {
		while (!St.hasMoreTokens()) {
			try {
				String line = in.readLine();
				St = new StringTokenizer(line);
			} catch (Exception e) {
				NOO(e);
			}
		}
		return St.nextToken();
	}

	private e(String name) {
		try {
			in = new BufferedReader(new FileReader(name + ".in"));
			St = new StringTokenizer("");
			out = new PrintWriter(new FileWriter(name + ".out"));
		} catch (Exception e) {
			NOO(e);
		}
	}

	private e() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			St = new StringTokenizer("");
			out = new PrintWriter(System.out);
		} catch (Exception e) {
			NOO(e);
		}
	}

	public static void main(String[] args) {
		Locale.setDefault(Locale.US);
		new e().run();
	}

}


/**
 * Codeforces Beta Round 15
 *
 * @author ProjectYoung
 */

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

public class CF15E {
  private static final int base = 1000000009;

  private long work(int k) {
    long[] powMod = new long[k + 3];
    powMod[0] = 1;
    for (int i = 1; i <= k + 2; i++) {
      powMod[i] = (powMod[i - 1] << 1) % base;
    }
    long res = 0;
    for (int i = 0; i < k; i++) {
      res += 4 * (powMod[i + 2] - 3);
    }
    return res % base;
  }

  private void solve(InputReader in, PrintWriter out) {
    // If n = 2, the answer is 10.
    int n = in.nextInt() - 2;
    long res = 10;
    long num = work(n >> 1);
    res += (num + 4) * num * 2;
    out.println(res % base);
  }

  public static void main(String[] args) {
    InputReader in = new InputReader(System.in);
    PrintWriter out = new PrintWriter(System.out);
    new CF15E().solve(in, out);
    out.close();
  }

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

    public InputReader(InputStream stream) {
      reader = new BufferedReader(new InputStreamReader(stream), 32768);
      tokenizer = null;
    }

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

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


import java.io.*;

public class CF506E {

    final static int MOD = 10007;

    static int[][] mul(int[][] a, int[][] b) {
        int[][] c = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            for (int j = 0; j < a.length; ++j) {
                for (int k = 0; k < a.length; ++k) {
                    c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % MOD;
                }
            }
        }
        return c;
    }

    static int[][] pow(int[][] a, long pow) {
        int[][] r = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            r[i][i] = 1;
        }
        while (pow > 0) {
            if (pow % 2 == 1) {
                r = mul(r, a);
            }
            pow /= 2;
            a = mul(a, a);
        }
        return r;
    }

    public static void solve(Input in, PrintWriter out) throws IOException {
        String s = in.next();
        int n = s.length();
        int k = n + in.nextInt();
        int[][][] d = new int[n + 1][n + 1][n + 1];
        d[0][n][0] = 1;
        for (int len = n; len > 0; --len) {
            for (int i = 0; i + len <= n; ++i) {
                for (int u = 0; u <= n; ++u) {
                    if (d[i][i + len][u] != 0) {
                        if (s.charAt(i) == s.charAt(i + len - 1)) {
                            d[i + 1][i + len - 1][u + 1] = (d[i + 1][i + len - 1][u + 1] + d[i][i + len][u]) % MOD;
                        } else {
                            d[i + 1][i + len][u] = (d[i + 1][i + len][u] + d[i][i + len][u]) % MOD;
                            d[i][i + len - 1][u] = (d[i][i + len - 1][u] + d[i][i + len][u]) % MOD;
                        }
                    }
                }
            }
        }
        int[][] d1 = new int[n + 1][n + 1];
        int[][] d2 = new int[n + 1][n + 1];
        for (int i = 0; i < n; ++i) {
            for (int u = 0; 2 * u <= n; ++u) {
                d1[u][n - 2 * u] += d[i][i][u];
                if (2 * u <= n - 1) {
                    d2[u][n - 2 * u - 1] += d[i][i + 1][u];
                }
            }
        }
        int ans = 0;
        for (int u = 0; u <= n; ++u) {
            for (int v = 0; v <= n; ++v) {
                if (d1[u][v] != 0) { // aa
                    int states = u + v + 1;
                    int[][] a = new int[states][states];
                    for (int i = 0; i < u; ++i) {
                        a[i][i] = 25;
                        a[i][i + 1] = 1;
                    }
                    for (int i = u; i < u + v; ++i) {
                        a[i][i] = 24;
                        a[i][i + 1] = 1;
                    }
                    a = pow(a, (k - 1) / 2);
                    int cur = a[0][states - 1];
                    if (k % 2 == 1) {
                        cur = cur * 26 % MOD;
                    }
                    ans = (ans + d1[u][v] * cur) % MOD;
//                    System.err.println("d1: " + u + " " + v + " " + d1[u][v] + " " + cur);
                }
                if (d2[u][v] != 0) { // a
                    int states = u + v + 2;
                    int[][] a = new int[states][states];
                    for (int i = 0; i < u; ++i) {
                        a[i][i] = 25;
                        a[i][i + 1] = 1;
                    }
                    for (int i = u; i < u + v; ++i) {
                        a[i][i] = 24;
                        a[i][i + 1] = 1;
                    }
                    a[u + v][u + v] = 25;
                    a[u + v][u + v + 1] = 1;
//                    System.err.println(Arrays.deepToString(a));
                    a = pow(a, (k + 1) / 2);
                    int cur = a[0][states - 1];
                    ans = (ans + d2[u][v] * cur) % MOD;
//                    System.err.println("d2: " + u + " " + v + " " + d2[u][v] + " " + cur);
                }
            }
        }
        out.println(ans);
        out.flush();
    }

    /*
0
0
6624
8739

     */

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
//        Random rnd = new Random(42);
//        while (rnd != null) {
//            int n = rnd.nextInt(200) + 1;
//            StringBuilder sb = new StringBuilder();
//            for (int i = 0; i < n; ++i) {
//                sb.append((char)('a' + rnd.nextInt(3)));
//            }
//            sb.append("\n");
//            sb.append(rnd.nextInt(100));
//            solve(new Input(sb.toString()), out);
//        }
        solve(new Input(new BufferedReader(new InputStreamReader(System.in))), out);
        out.close();
    }

    static class Input {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();

        public Input(BufferedReader in) {
            this.in = in;
        }

        public Input(String s) {
            this.in = new BufferedReader(new StringReader(s));
        }

        public String next() throws IOException {
            sb.setLength(0);
            while (true) {
                int c = in.read();
                if (c == -1) {
                    return null;
                }
                if (" \n\r\t".indexOf(c) == -1) {
                    sb.append((char)c);
                    break;
                }
            }
            while (true) {
                int c = in.read();
                if (c == -1 || " \n\r\t".indexOf(c) != -1) {
                    break;
                }
                sb.append((char)c);
            }
            return sb.toString();
        }

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

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

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


import java.util.Arrays;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Random;
import java.util.HashMap;
import java.io.BufferedReader;
import java.util.Map;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

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

class TaskE {
    static final int MODULO = 10007;
    int magic;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        String s = in.next();
        int n = in.nextInt() + s.length();
        int[][][] ways = new int[s.length()][s.length() + 1][s.length() / 2 + 2];
        int[][] waysAll = new int[3][s.length() / 2 + 1];
        ways[0][s.length()][0] = 1;
        for (int start = 0; start < s.length(); ++start)
            for (int len = s.length() - start; len >= 1; --len) {
                int[] src = ways[start][len];
                if (s.charAt(start) == s.charAt(start + len - 1)) {
                    int nlen = len - 2;
                    int[] dest;
                    if (nlen <= 0) {
                        dest = waysAll[len];
                    } else {
                        dest = ways[start + 1][nlen];
                    }
                    for (int doubles = 0; doubles < src.length; ++doubles) if (src[doubles] != 0) {
                        dest[doubles + 1] = (dest[doubles + 1] + src[doubles]) % MODULO;
                    }
                } else {
                    int nlen = len - 1;
                    int[] dest = ways[start][nlen];
                    for (int doubles = 0; doubles < src.length; ++doubles) if (src[doubles] != 0) {
                        dest[doubles] = (dest[doubles] + src[doubles]) % MODULO;
                    }
                    dest = ways[start + 1][nlen];
                    for (int doubles = 0; doubles < src.length; ++doubles) if (src[doubles] != 0) {
                        dest[doubles] = (dest[doubles] + src[doubles]) % MODULO;
                    }
                }
            }
        int steps = n / 2;
        int ret = 0;
        int maxSingles = s.length();
        int maxDoubles = waysAll[1].length - 1;
        int size = maxSingles + maxDoubles + maxDoubles;
        magic = maxDoubles + maxSingles;
        int[][] m = new int[size][size];
        for (int i = 0; i < maxSingles + maxDoubles + maxDoubles; ++i) {
            if (i + 1 < maxSingles + maxDoubles) m[i + 1][i] = 1;
            if (i >= maxSingles && i < maxSingles + maxDoubles) m[i + maxDoubles][i] = 1;
            m[i][i] = (i < maxSingles ? 24 : (i < maxSingles + maxDoubles ? 25 : 26));
        }
        m = pow(m, steps);
        for (int last = 1; last <= 2; ++last) {
            for (int doubles = 0; doubles < waysAll[last].length; ++doubles) {
                int w = waysAll[last][doubles];
                if (w != 0) {
                    int singles = s.length() + (last == 1 ? 1 : 0) - 2 * doubles;
                    if (n % 2 == 0) {
                        ret = (int) ((ret + (long) w * m[maxSingles + maxDoubles + doubles - 1][maxSingles - singles]) % MODULO);
                    } else {
                        ret = (int) ((ret + (long) w * m[maxSingles + maxDoubles + doubles - 1][maxSingles - singles] * 26) % MODULO);
                        if (last == 1) {
                            ret = (int) ((ret + (long) w * m[maxSingles + doubles - 1][maxSingles - singles]) % MODULO);
                        }
                    }
                }
            }
        }
        out.println(ret);
    }

    private int[][] pow(int[][] m, int k) {
        int[][] res = new int[m.length][m.length];
        for (int i = 0; i < m.length; ++i) res[i][i] = 1;
        while (k > 0) {
            System.err.println(k + " " + m.length);
            if (k % 2 != 0) {
                res = mul(m, res);
            }
            k /= 2;
            m = mul(m, m);
        }
        return res;
    }

    private final int BIG = Integer.MAX_VALUE - Integer.MAX_VALUE % MODULO;

    private int[][] mul(int[][] a, int[][] b) {
        int n = a.length;
        int[][] c = new int[n][n];
        for (int i = 0; i < c.length; ++i) {
            for (int j = 0; j < magic; ++j) {
                int s = 0;
                for (int k = 0; k < magic; ++k) {
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                if (i >= magic) {
                    int k = i;
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                c[i][j] = s % MODULO;
            }
            if (i >= magic) {
                int j = i;
                int s = 0;
                for (int k = 0; k < magic; ++k) {
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                if (i >= magic) {
                    int k = i;
                    s += a[i][k] * b[k][j];
                    if (s < 0)
                        s -= BIG;
                }
                c[i][j] = s % MODULO;
            }
        }
        return c;
    }

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

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

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

}


import java.io.*;

public class CF506E {

    final static int MOD = 10007;

    static int[][] mul(int[][] a, int[][] b) {
        int[][] c = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            for (int j = i; j < a.length; ++j) {
                long sum = 0;
                for (int k = i; k <= j; ++k) {
                    sum += a[i][k] * b[k][j];
                }
                c[i][j] = (int) (sum % MOD);
            }
        }
        return c;
    }

    static int[][] pow(int[][] a, long pow) {
        int[][] r = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            r[i][i] = 1;
        }
        while (pow > 0) {
            if (pow % 2 == 1) {
                r = mul(r, a);
            }
            pow /= 2;
            a = mul(a, a);
        }
        return r;
    }

    public static void solve(Input in, PrintWriter out) throws IOException {
        String s = in.next();
        int n = s.length();
        int k = n + in.nextInt();
        int[][][] d = new int[n + 1][n + 1][n + 1];
        d[0][n][0] = 1;
        for (int len = n; len > 0; --len) {
            for (int i = 0; i + len <= n; ++i) {
                for (int u = 0; u <= n; ++u) {
                    if (d[i][i + len][u] != 0) {
                        if (s.charAt(i) == s.charAt(i + len - 1)) {
                            d[i + 1][i + len - 1][u + 1] = (d[i + 1][i + len - 1][u + 1] + d[i][i + len][u]) % MOD;
                        } else {
                            d[i + 1][i + len][u] = (d[i + 1][i + len][u] + d[i][i + len][u]) % MOD;
                            d[i][i + len - 1][u] = (d[i][i + len - 1][u] + d[i][i + len][u]) % MOD;
                        }
                    }
                }
            }
        }
        int[][] d1 = new int[n + 1][n + 1];
        int[][] d2 = new int[n + 1][n + 1];
        for (int i = 0; i < n; ++i) {
            for (int u = 0; 2 * u <= n; ++u) {
                d1[u][n - 2 * u] += d[i][i][u];
                if (2 * u <= n - 1) {
                    d2[u][n - 2 * u - 1] += d[i][i + 1][u];
                }
            }
        }
        int ans = 0;
        int[][] a0 = new int[3 * n + 1][3 * n + 1];
        for (int i = 0; i < n; ++i) {
            a0[i][i] = 25;
            a0[i][i + 1] = 1;
            if (i + 1 == n) {
                a0[i][2 * n] = 1;
            }
        }
        for (int i = n; i < 2 * n; ++i) {
            a0[i][i] = 24;
            if (i + 1 != 2 * n) {
                a0[i][i + 1] = 1;
            }
            a0[i][n + i + 1] = 1;
        }
        int[][] a0low = pow(a0, (k - 1) / 2);
        int[][] a0high = k % 2 == 1 ? a0low : mul(a0low, a0);
        for (int u = 0; u <= n; ++u) {
            for (int v = 0; v <= n; ++v) {
                if (d1[u][v] != 0 && d2[u][v] != 0) {
                    System.err.println("here");
                }
                if (d1[u][v] != 0) { // aa
                    int cur = a0low[n - u][2 * n + v];
                    if (k % 2 == 1) {
                        cur = cur * 26 % MOD;
                    }
                    ans = (ans + d1[u][v] * cur) % MOD;
//                    System.err.println("d1: " + u + " " + v + " " + d1[u][v] + " " + cur);
                }
                if (d2[u][v] != 0) { // a
                    int cur = a0high[n - u - 1][2 * n + v];
                    ans = (ans + d2[u][v] * cur) % MOD;
//                    System.err.println("d2: " + u + " " + v + " " + d2[u][v] + " " + cur);
                }
            }
        }
        out.println(ans);
        out.flush();
    }

    /*
0 78
0 76
6624 57
8739 55
0 123
0 93
0 99
1871 122
6968 75
8247 1
0 79
3404 10
0 19
0 85
4715 23
8609 1
1910 86
721 113
4055 12
659 82
0 115
0 53
944 57
9422 11

     */

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
//        Random rnd = new Random(42);
//        while (rnd != null) {
//            int n = 200;
//            StringBuilder sb = new StringBuilder();
//            for (int i = 0; i < n; ++i) {
//                sb.append((char)('a' + rnd.nextInt(3)));
//            }
//            sb.append("\n");
//            sb.append(rnd.nextInt(100));
//            solve(new Input(sb.toString()), out);
////            return;
//        }
        solve(new Input(new BufferedReader(new InputStreamReader(System.in))), out);
        out.close();
    }

    static class Input {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();

        public Input(BufferedReader in) {
            this.in = in;
        }

        public Input(String s) {
            this.in = new BufferedReader(new StringReader(s));
        }

        public String next() throws IOException {
            sb.setLength(0);
            while (true) {
                int c = in.read();
                if (c == -1) {
                    return null;
                }
                if (" \n\r\t".indexOf(c) == -1) {
                    sb.append((char)c);
                    break;
                }
            }
            while (true) {
                int c = in.read();
                if (c == -1 || " \n\r\t".indexOf(c) != -1) {
                    break;
                }
                sb.append((char)c);
            }
            return sb.toString();
        }

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

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

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


import java.io.*;

public class CF506E {

    final static int MOD = 10007;

    static int[][] mul(int[][] a, int[][] b) {
        int[][] c = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            for (int j = i; j < a.length; ++j) {
                long sum = 0;
                for (int k = i; k <= j; ++k) {
                    sum += a[i][k] * b[k][j];
                }
                c[i][j] = (int) (sum % MOD);
            }
        }
        return c;
    }

    static int[][] pow(int[][] a, long pow) {
        int[][] r = new int[a.length][a.length];
        for (int i = 0; i < a.length; ++i) {
            r[i][i] = 1;
        }
        while (pow > 0) {
            if (pow % 2 == 1) {
                r = mul(r, a);
            }
            pow /= 2;
            a = mul(a, a);
        }
        return r;
    }

    public static void solve(Input in, PrintWriter out) throws IOException {
        String s = in.next();
        int n = s.length();
        int k = n + in.nextInt();
        int[][][] d = new int[n + 1][n + 1][n + 1];
        d[0][n][0] = 1;
        for (int len = n; len > 0; --len) {
            for (int i = 0; i + len <= n; ++i) {
                for (int u = 0; u <= n; ++u) {
                    if (d[i][i + len][u] != 0) {
                        if (s.charAt(i) == s.charAt(i + len - 1)) {
                            d[i + 1][i + len - 1][u + 1] = (d[i + 1][i + len - 1][u + 1] + d[i][i + len][u]) % MOD;
                        } else {
                            d[i + 1][i + len][u] = (d[i + 1][i + len][u] + d[i][i + len][u]) % MOD;
                            d[i][i + len - 1][u] = (d[i][i + len - 1][u] + d[i][i + len][u]) % MOD;
                        }
                    }
                }
            }
        }
        int[][] d1 = new int[n + 1][n + 1];
        int[][] d2 = new int[n + 1][n + 1];
        for (int i = 0; i < n; ++i) {
            for (int u = 0; 2 * u <= n; ++u) {
                d1[u][n - 2 * u] += d[i][i][u];
                if (2 * u <= n - 1) {
                    d2[u][n - 2 * u - 1] += d[i][i + 1][u];
                }
            }
        }
        int ans = 0;
        int[][] a0 = new int[3 * n + 1][3 * n + 1];
        for (int i = 0; i < n; ++i) {
            a0[i][i] = 25;
            a0[i][i + 1] = 1;
            if (i + 1 == n) {
                a0[i][2 * n] = 1;
            }
        }
        for (int i = n; i < 2 * n; ++i) {
            a0[i][i] = 24;
            if (i + 1 != 2 * n) {
                a0[i][i + 1] = 1;
            }
            a0[i][n + i + 1] = 1;
        }
        int[][] a0low = pow(a0, (k - 1) / 2);
        int[][] a0high = mul(a0low, a0);
        for (int u = 0; u <= n; ++u) {
            for (int v = 0; v <= n; ++v) {
                if (d1[u][v] != 0 && d2[u][v] != 0) {
                    System.err.println("here");
                }
                if (d1[u][v] != 0) { // aa
                    int cur = a0low[n - u][2 * n + v];
                    if (k % 2 == 1) {
                        cur = cur * 26 % MOD;
                    }
                    ans = (ans + d1[u][v] * cur) % MOD;
//                    System.err.println("d1: " + u + " " + v + " " + d1[u][v] + " " + cur);
                }
                if (d2[u][v] != 0) { // a
                    int cur = a0high[n - u - 1][2 * n + v];
                    ans = (ans + d2[u][v] * cur) % MOD;
//                    System.err.println("d2: " + u + " " + v + " " + d2[u][v] + " " + cur);
                }
            }
        }
        out.println(ans);
        out.flush();
    }

    /*
0 78
0 76
6624 57
8739 55
0 123
0 93
0 99
1871 122
6968 75
8247 1
0 79
3404 10
0 19
0 85
4715 23
8609 1
1910 86
721 113
4055 12
659 82
0 115
0 53
944 57
9422 11

     */

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
//        Random rnd = new Random(42);
//        while (rnd != null) {
//            int n = 200;
//            StringBuilder sb = new StringBuilder();
//            for (int i = 0; i < n; ++i) {
//                sb.append((char)('a' + rnd.nextInt(3)));
//            }
//            sb.append("\n");
//            sb.append(rnd.nextInt(100));
//            solve(new Input(sb.toString()), out);
////            return;
//        }
        solve(new Input(new BufferedReader(new InputStreamReader(System.in))), out);
        out.close();
    }

    static class Input {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();

        public Input(BufferedReader in) {
            this.in = in;
        }

        public Input(String s) {
            this.in = new BufferedReader(new StringReader(s));
        }

        public String next() throws IOException {
            sb.setLength(0);
            while (true) {
                int c = in.read();
                if (c == -1) {
                    return null;
                }
                if (" \n\r\t".indexOf(c) == -1) {
                    sb.append((char)c);
                    break;
                }
            }
            while (true) {
                int c = in.read();
                if (c == -1 || " \n\r\t".indexOf(c) != -1) {
                    break;
                }
                sb.append((char)c);
            }
            return sb.toString();
        }

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

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

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