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

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

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

    static class FCards {
        Modular mod = new Modular(998244353);
        Composite comp = new Composite(5000, mod);
        Power power = new Power(mod);

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

            CachedPow pm = new CachedPow(m, mod);
            int[] xk = new int[k + 1];
            for (int i = 0; i <= k; i++) {
                xk[i] = power.pow(i, k);
            }

            int ans = 0;
            BinomialComposite bc = new BinomialComposite(n, k, mod, true);
            for (int t = 0; t <= k; t++) {
                int p1 = bc.get(t);
                int p2 = 0;
                for (int i = 0; i <= t; i++) {
                    int contrib = comp.composite(t, i);
                    contrib = mod.mul(contrib, xk[t - i]);
                    if (i % 2 == 1) {
                        contrib = mod.valueOf(-contrib);
                    }
                    p2 = mod.plus(p2, contrib);
                }
                int p3 = pm.inverse(t);

                int contrib = mod.mul(p1, p2);
                contrib = mod.mul(contrib, p3);
                ans = mod.plus(ans, contrib);
            }

            out.println(ans);
        }

    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public int valueOf(int x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return x;
        }

        public int valueOf(long x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return (int) x;
        }

        public int mul(int x, int y) {
            return valueOf((long) x * y);
        }

        public int plus(int x, int y) {
            return valueOf(x + y);
        }

        public Modular getModularForPowerComputation() {
            return new Modular(m - 1);
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static class IntegerList implements Cloneable {
        private int size;
        private int cap;
        private int[] data;
        private static final int[] EMPTY = new int[0];

        public int[] getData() {
            return data;
        }

        public void remove(int l, int r) {
            if (l > r) {
                return;
            }
            checkRange(l);
            checkRange(r);
            if (r == size - 1) {
                size = l;
                return;
            } else {
                System.arraycopy(data, r + 1, data, l, size - (r + 1));
                size -= (r - l + 1);
            }
        }

        public IntegerList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new int[cap];
            }
        }

        public IntegerList(IntegerList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public IntegerList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException("index " + i + " out of range");
            }
        }

        public int get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(int x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(int[] x) {
            addAll(x, 0, x.length);
        }

        public void addAll(int[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(IntegerList list) {
            addAll(list.data, 0, list.size);
        }

        public void expandWith(int x, int len) {
            ensureSpace(len);
            while (size < len) {
                data[size++] = x;
            }
        }

        public void set(int i, int x) {
            checkRange(i);
            data[i] = x;
        }

        public int size() {
            return size;
        }

        public int[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof IntegerList)) {
                return false;
            }
            IntegerList other = (IntegerList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Integer.hashCode(data[i]);
            }
            return h;
        }

        public IntegerList clone() {
            IntegerList ans = new IntegerList();
            ans.addAll(this);
            return ans;
        }

    }

    static class InverseNumber {
        int[] inv;

        public InverseNumber(int[] inv, int limit, Modular modular) {
            this.inv = inv;
            inv[1] = 1;
            int p = modular.getMod();
            for (int i = 2; i <= limit; i++) {
                int k = p / i;
                int r = p % i;
                inv[i] = modular.mul(-k, inv[r]);
            }
        }

        public InverseNumber(int limit, Modular modular) {
            this(new int[limit + 1], limit, modular);
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static long round(double x) {
            if (x >= 0) {
                return (long) (x + 0.5);
            } else {
                return (long) (x - 0.5);
            }
        }

    }

    static class Composite {
        final Factorial factorial;
        final Modular modular;

        public Composite(Factorial factorial) {
            this.factorial = factorial;
            this.modular = factorial.getModular();
        }

        public Composite(int limit, Modular modular) {
            this(new Factorial(limit, modular));
        }

        public int composite(int m, int n) {
            if (n > m) {
                return 0;
            }
            return modular.mul(modular.mul(factorial.fact(m), factorial.invFact(n)), factorial.invFact(m - n));
        }

    }

    static class SequenceUtils {
        public static void swap(double[] data, int i, int j) {
            double tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }

        public static boolean equal(int[] a, int al, int ar, int[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

    static class FastFourierTransform {
        private static double[][] realLevels = new double[30][];
        private static double[][] imgLevels = new double[30][];

        private static void prepareLevel(int i) {
            if (realLevels[i] == null) {
                realLevels[i] = new double[1 << i];
                imgLevels[i] = new double[1 << i];
                for (int j = 0, s = 1 << i; j < s; j++) {
                    realLevels[i][j] = Math.cos(Math.PI / s * j);
                    imgLevels[i][j] = Math.sin(Math.PI / s * j);
                }
            }
        }

        public static void dft(double[][] p, int m) {
            int n = 1 << m;

            int shift = 32 - Integer.numberOfTrailingZeros(n);
            for (int i = 1; i < n; i++) {
                int j = Integer.reverse(i << shift);
                if (i < j) {
                    SequenceUtils.swap(p[0], i, j);
                    SequenceUtils.swap(p[1], i, j);
                }
            }

            double[][] t = new double[2][1];
            for (int d = 0; d < m; d++) {
                int s = 1 << d;
                int s2 = s << 1;
                prepareLevel(d);
                for (int i = 0; i < n; i += s2) {
                    for (int j = 0; j < s; j++) {
                        int a = i + j;
                        int b = a + s;
                        mul(realLevels[d][j], imgLevels[d][j], p[0][b], p[1][b], t, 0);
                        sub(p[0][a], p[1][a], t[0][0], t[1][0], p, b);
                        add(p[0][a], p[1][a], t[0][0], t[1][0], p, a);
                    }
                }
            }
        }

        public static void idft(double[][] p, int m) {
            dft(p, m);

            int n = 1 << m;
            div(p[0][0], p[1][0], n, p, 0);
            div(p[0][n / 2], p[1][n / 2], n, p, n / 2);
            for (int i = 1, until = n / 2; i < until; i++) {
                double a = p[0][n - i];
                double b = p[1][n - i];
                div(p[0][i], p[1][i], n, p, n - i);
                div(a, b, n, p, i);
            }
        }

        private static void add(double r1, double i1, double r2, double i2, double[][] r, int i) {
            r[0][i] = r1 + r2;
            r[1][i] = i1 + i2;
        }

        private static void sub(double r1, double i1, double r2, double i2, double[][] r, int i) {
            r[0][i] = r1 - r2;
            r[1][i] = i1 - i2;
        }

        private static void mul(double r1, double i1, double r2, double i2, double[][] r, int i) {
            r[0][i] = r1 * r2 - i1 * i2;
            r[1][i] = r1 * i2 + i1 * r2;
        }

        private static void div(double r1, double i1, double r2, double[][] r, int i) {
            r[0][i] = r1 / r2;
            r[1][i] = i1 / r2;
        }

        public static int[] multiplyMod(int[] a, int aLen, int[] b, int bLen, int m) {
            int need = aLen + bLen - 1;
            int n = 1 << CachedLog2.ceilLog(need);

            double[] aReal = new double[n];
            double[] aImag = new double[n];
            for (int i = 0; i < aLen; i++) {
                int x = (a[i] % m + m) % m;
                aReal[i] = x & ((1 << 15) - 1);
                aImag[i] = x >> 15;
            }
            dft(new double[][]{aReal, aImag}, CachedLog2.floorLog(n));

            double[] bReal = new double[n];
            double[] bImag = new double[n];
            for (int i = 0; i < bLen; i++) {
                int x = (b[i] % m + m) % m;
                bReal[i] = x & ((1 << 15) - 1);
                bImag[i] = x >> 15;
            }
            dft(new double[][]{bReal, bImag}, CachedLog2.floorLog(n));

            double[] faReal = new double[n];
            double[] faImag = new double[n];
            double[] fbReal = new double[n];
            double[] fbImag = new double[n];

            for (int i = 0; i < n; i++) {
                int j = (n - i) & (n - 1);

                double a1r = (aReal[i] + aReal[j]) / 2;
                double a1i = (aImag[i] - aImag[j]) / 2;
                double a2r = (aImag[i] + aImag[j]) / 2;
                double a2i = (aReal[j] - aReal[i]) / 2;

                double b1r = (bReal[i] + bReal[j]) / 2;
                double b1i = (bImag[i] - bImag[j]) / 2;
                double b2r = (bImag[i] + bImag[j]) / 2;
                double b2i = (bReal[j] - bReal[i]) / 2;

                faReal[i] = a1r * b1r - a1i * b1i - a2r * b2i - a2i * b2r;
                faImag[i] = a1r * b1i + a1i * b1r + a2r * b2r - a2i * b2i;

                fbReal[i] = a1r * b2r - a1i * b2i + a2r * b1r - a2i * b1i;
                fbImag[i] = a1r * b2i + a1i * b2r + a2r * b1i + a2i * b1r;
            }

            idft(new double[][]{faReal, faImag}, CachedLog2.floorLog(n));
            idft(new double[][]{fbReal, fbImag}, CachedLog2.floorLog(n));
            int[] res = new int[need];
            for (int i = 0; i < need; i++) {
                long aa = (long) (faReal[i] + 0.5);
                long bb = (long) (fbReal[i] + 0.5);
                long cc = (long) (faImag[i] + 0.5);
                res[i] = (int) ((aa % m + (bb % m << 15) + (cc % m << 30)) % m);
            }
            return res;
        }

    }

    static class Loop<T> {
        T[] data;
        int pos;

        public Loop(T... data) {
            this.data = data;
        }

        public T turn(int i) {
            pos += i;
            return get(0);
        }

        public T turn() {
            return turn(1);
        }

        public T get(int i) {
            return data[(pos + i) % data.length];
        }

        public T get() {
            return get(0);
        }

    }

    static class BinomialComposite {
        private int m;
        private long n;
        private Modular mod;
        private IntegerList composites;
        private boolean fft;

        public BinomialComposite(long n, int m, Modular mod, boolean fft) {
            this.m = m;
            this.mod = mod;
            this.n = n;
            this.fft = fft;
            composites = pow(n);
            composites.expandWith(0, m + 1);
        }

        public int get(int i) {
            return composites.get(i);
        }

        private void mul(IntegerList a, IntegerList b, IntegerList c) {
            if (!fft) {
                Polynomials.mul(a, b, c, mod);
            } else {
                int[] ans = FastFourierTransform.multiplyMod(a.getData(), a.size(), b.getData(), b.size(), mod.getMod());
                c.clear();
                c.addAll(ans);
            }
            trim(c);
        }

        private void trim(IntegerList x) {
            if (x.size() > m + 1) {
                x.remove(m + 1, x.size() - 1);
            }
        }

        private void mul(IntegerList p, IntegerList ans) {
            ans.clear();
            ans.expandWith(0, p.size() + 1);

            int n = p.size();
            for (int i = 0; i < n; i++) {
                int val = p.get(i);
                ans.set(i, mod.plus(ans.get(i), val));
                ans.set(i + 1, val);
            }

            trim(ans);
        }

        private IntegerList pow(long exp) {
            int ceil = CachedLog2.ceilLog(m + 1 + m);
            Loop<IntegerList> loop = new Loop<>(new IntegerList(1 << ceil), new IntegerList(1 << ceil));
            loop.get().add(1);
            for (int i = CachedLog2.floorLog(exp); i >= 0; i--) {
                mul(loop.get(), loop.get(), loop.turn());
                if (1 == Bits.bitAt(exp, i)) {
                    mul(loop.get(), loop.turn());
                }
            }
            return loop.get();
        }

    }

    static class Bits {
        private Bits() {
        }

        public static int bitAt(long x, int i) {
            return (int) ((x >> i) & 1);
        }

    }

    static class Factorial {
        int[] fact;
        int[] inv;
        Modular modular;

        public Modular getModular() {
            return modular;
        }

        public Factorial(int[] fact, int[] inv, InverseNumber in, int limit, Modular modular) {
            this.modular = modular;
            this.fact = fact;
            this.inv = inv;
            fact[0] = inv[0] = 1;
            for (int i = 1; i <= limit; i++) {
                fact[i] = modular.mul(fact[i - 1], i);
                inv[i] = modular.mul(inv[i - 1], in.inv[i]);
            }
        }

        public Factorial(int limit, Modular modular) {
            this(new int[limit + 1], new int[limit + 1], new InverseNumber(limit, modular), limit, modular);
        }

        public int fact(int n) {
            return fact[n];
        }

        public int invFact(int n) {
            return inv[n];
        }

    }

    static class CachedPow {
        private int[] first;
        private int[] second;
        private Modular mod;
        private Modular powMod;

        public CachedPow(int x, Modular mod) {
            this(x, mod.getMod(), mod);
        }

        public CachedPow(int x, int maxExp, Modular mod) {
            this.mod = mod;
            this.powMod = mod.getModularForPowerComputation();
            int k = Math.max(1, (int) DigitUtils.round(Math.sqrt(maxExp)));
            first = new int[k];
            second = new int[maxExp / k + 1];
            first[0] = 1;
            for (int i = 1; i < k; i++) {
                first[i] = mod.mul(x, first[i - 1]);
            }
            second[0] = 1;
            int step = mod.mul(x, first[k - 1]);
            for (int i = 1; i < second.length; i++) {
                second[i] = mod.mul(second[i - 1], step);
            }
        }

        public int pow(int exp) {
            return mod.mul(first[exp % first.length], second[exp / first.length]);
        }

        public int inverse(int exp) {
            return pow(powMod.valueOf(-exp));
        }

    }

    static class Polynomials {
        public static int rankOf(IntegerList p) {
            int[] data = p.getData();
            int r = p.size() - 1;
            while (r >= 0 && data[r] == 0) {
                r--;
            }
            return Math.max(0, r);
        }

        public static void mul(IntegerList a, IntegerList b, IntegerList c, Modular mod) {
            int rA = rankOf(a);
            int rB = rankOf(b);
            c.clear();
            c.expandWith(0, rA + rB + 1);
            int[] aData = a.getData();
            int[] bData = b.getData();
            int[] cData = c.getData();
            for (int i = 0; i <= rA; i++) {
                for (int j = 0; j <= rB; j++) {
                    cData[i + j] = mod.plus(cData[i + j], mod.mul(aData[i], bData[j]));
                }
            }
        }

    }

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

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

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

        public FastOutput println(int c) {
            cache.append(c).append('\n');
            return this;
        }

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

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

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

    }

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

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

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

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

        public int readInt() {
            int sign = 1;

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

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

            return val;
        }

    }

    static class Power {
        final Modular modular;

        public Power(Modular modular) {
            this.modular = modular;
        }

        public int pow(int x, int n) {
            if (n == 0) {
                return modular.valueOf(1);
            }
            long r = pow(x, n >> 1);
            r = modular.valueOf(r * r);
            if ((n & 1) == 1) {
                r = modular.valueOf(r * x);
            }
            return (int) r;
        }

    }

    static class CachedLog2 {
        private static final int BITS = 16;
        private static final int LIMIT = 1 << BITS;
        private static final byte[] CACHE = new byte[LIMIT];

        static {
            int b = 0;
            for (int i = 0; i < LIMIT; i++) {
                while ((1 << (b + 1)) <= i) {
                    b++;
                }
                CACHE[i] = (byte) b;
            }
        }

        public static int ceilLog(int x) {
            int ans = floorLog(x);
            if ((1 << ans) < x) {
                ans++;
            }
            return ans;
        }

        public static int floorLog(int x) {
            return x < LIMIT ? CACHE[x] : (BITS + CACHE[x >>> BITS]);
        }

        public static int floorLog(long x) {
            int ans = 0;
            while (x >= LIMIT) {
                ans += BITS;
                x >>>= BITS;
            }
            return ans + CACHE[(int) x];
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Sparsh Sanchorawala
 */
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);
        FCards solver = new FCards();
        solver.solve(1, in, out);
        out.close();
    }

    static class FCards {
        long mod = 998244353;

        long modExp(long x, long y) {
            if (y == 0)
                return 1;
            if (y == 1)
                return x;
            long ret = modExp(x, y >> 1);
            ret = ret * ret % mod;
            if ((y & 1) == 1)
                ret = ret * x % mod;
            return ret;
        }

        public void solve(int testNumber, InputReader s, PrintWriter w) {
            int n = s.nextInt(), m = s.nextInt(), k = s.nextInt();
            //dp[tuple size][number of distinct elements] = number of such tuples
            long[][] dp = new long[k + 1][Math.min(n, k) + 1];
            dp[0][0] = 1;
            for (int i = 1; i <= k; i++) {
                for (int j = 1; j <= Math.min(n, k); j++) {
                    dp[i][j] = (dp[i][j] + dp[i - 1][j] * j % mod) % mod;
                    dp[i][j] = (dp[i][j] + dp[i - 1][j - 1] * (n - j + 1) % mod) % mod;
                }
            }
            long invm = modExp(m, mod - 2);
            long res = 0;
            long prob = 1;
            for (int i = 0; i <= Math.min(n, k); i++) {
                res = (res + dp[k][i] * prob % mod) % mod;
                prob = prob * invm % mod;
            }
            w.println(res);
        }

    }

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

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

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

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

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

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

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

        }

    }
}


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

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

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

    static class FCards {
        Modular mod = new Modular(998244353);
        Composite comp = new Composite(5000, mod);
        Power power = new Power(mod);

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

            CachedPow pm = new CachedPow(m, mod);
            int[] xk = new int[k + 1];
            for (int i = 0; i <= k; i++) {
                xk[i] = power.pow(i, k);
            }

            int ans = 0;
            BinomialComposite bc = new BinomialComposite(n, k, mod);
            for (int t = 0; t <= k; t++) {
                int p1 = bc.get(t);
                int p2 = 0;
                for (int i = 0; i <= t; i++) {
                    int contrib = comp.composite(t, i);
                    contrib = mod.mul(contrib, xk[t - i]);
                    if (i % 2 == 1) {
                        contrib = mod.valueOf(-contrib);
                    }
                    p2 = mod.plus(p2, contrib);
                }
                int p3 = pm.inverse(t);

                int contrib = mod.mul(p1, p2);
                contrib = mod.mul(contrib, p3);
                ans = mod.plus(ans, contrib);
            }

            out.println(ans);
        }

    }

    static class IntegerList implements Cloneable {
        private int size;
        private int cap;
        private int[] data;
        private static final int[] EMPTY = new int[0];

        public int[] getData() {
            return data;
        }

        public void remove(int l, int r) {
            if (l > r) {
                return;
            }
            checkRange(l);
            checkRange(r);
            if (r == size - 1) {
                size = l;
                return;
            } else {
                System.arraycopy(data, r + 1, data, l, size - (r + 1));
                size -= (r - l + 1);
            }
        }

        public IntegerList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new int[cap];
            }
        }

        public IntegerList(IntegerList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public IntegerList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException("index " + i + " out of range");
            }
        }

        public int get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(int x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(int[] x) {
            addAll(x, 0, x.length);
        }

        public void addAll(int[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(IntegerList list) {
            addAll(list.data, 0, list.size);
        }

        public void expandWith(int x, int len) {
            ensureSpace(len);
            while (size < len) {
                data[size++] = x;
            }
        }

        public void set(int i, int x) {
            checkRange(i);
            data[i] = x;
        }

        public int size() {
            return size;
        }

        public int[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof IntegerList)) {
                return false;
            }
            IntegerList other = (IntegerList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Integer.hashCode(data[i]);
            }
            return h;
        }

        public IntegerList clone() {
            IntegerList ans = new IntegerList();
            ans.addAll(this);
            return ans;
        }

    }

    static class FastFourierTransform {
        private static double[][] realLevels = new double[30][];
        private static double[][] imgLevels = new double[30][];

        private static void prepareLevel(int i) {
            if (realLevels[i] == null) {
                realLevels[i] = new double[1 << i];
                imgLevels[i] = new double[1 << i];
                for (int j = 0, s = 1 << i; j < s; j++) {
                    realLevels[i][j] = Math.cos(Math.PI / s * j);
                    imgLevels[i][j] = Math.sin(Math.PI / s * j);
                }
            }
        }

        public static void dft(double[][] p, int m) {
            int n = 1 << m;

            int shift = 32 - Integer.numberOfTrailingZeros(n);
            for (int i = 1; i < n; i++) {
                int j = Integer.reverse(i << shift);
                if (i < j) {
                    SequenceUtils.swap(p[0], i, j);
                    SequenceUtils.swap(p[1], i, j);
                }
            }

            double[][] t = new double[2][1];
            for (int d = 0; d < m; d++) {
                int s = 1 << d;
                int s2 = s << 1;
                prepareLevel(d);
                for (int i = 0; i < n; i += s2) {
                    for (int j = 0; j < s; j++) {
                        int a = i + j;
                        int b = a + s;
                        mul(realLevels[d][j], imgLevels[d][j], p[0][b], p[1][b], t, 0);
                        sub(p[0][a], p[1][a], t[0][0], t[1][0], p, b);
                        add(p[0][a], p[1][a], t[0][0], t[1][0], p, a);
                    }
                }
            }
        }

        public static void idft(double[][] p, int m) {
            dft(p, m);

            int n = 1 << m;
            div(p[0][0], p[1][0], n, p, 0);
            div(p[0][n / 2], p[1][n / 2], n, p, n / 2);
            for (int i = 1, until = n / 2; i < until; i++) {
                double a = p[0][n - i];
                double b = p[1][n - i];
                div(p[0][i], p[1][i], n, p, n - i);
                div(a, b, n, p, i);
            }
        }

        private static void add(double r1, double i1, double r2, double i2, double[][] r, int i) {
            r[0][i] = r1 + r2;
            r[1][i] = i1 + i2;
        }

        private static void sub(double r1, double i1, double r2, double i2, double[][] r, int i) {
            r[0][i] = r1 - r2;
            r[1][i] = i1 - i2;
        }

        private static void mul(double r1, double i1, double r2, double i2, double[][] r, int i) {
            r[0][i] = r1 * r2 - i1 * i2;
            r[1][i] = r1 * i2 + i1 * r2;
        }

        private static void div(double r1, double i1, double r2, double[][] r, int i) {
            r[0][i] = r1 / r2;
            r[1][i] = i1 / r2;
        }

        public static int[] multiplyMod(int[] a, int aLen, int[] b, int bLen, int m) {
            int need = aLen + bLen - 1;
            int n = 1 << CachedLog2.ceilLog(need);

            double[] aReal = new double[n];
            double[] aImag = new double[n];
            for (int i = 0; i < aLen; i++) {
                int x = (a[i] % m + m) % m;
                aReal[i] = x & ((1 << 15) - 1);
                aImag[i] = x >> 15;
            }
            dft(new double[][]{aReal, aImag}, CachedLog2.floorLog(n));

            double[] bReal = new double[n];
            double[] bImag = new double[n];
            for (int i = 0; i < bLen; i++) {
                int x = (b[i] % m + m) % m;
                bReal[i] = x & ((1 << 15) - 1);
                bImag[i] = x >> 15;
            }
            dft(new double[][]{bReal, bImag}, CachedLog2.floorLog(n));

            double[] faReal = new double[n];
            double[] faImag = new double[n];
            double[] fbReal = new double[n];
            double[] fbImag = new double[n];

            for (int i = 0; i < n; i++) {
                int j = (n - i) & (n - 1);

                double a1r = (aReal[i] + aReal[j]) / 2;
                double a1i = (aImag[i] - aImag[j]) / 2;
                double a2r = (aImag[i] + aImag[j]) / 2;
                double a2i = (aReal[j] - aReal[i]) / 2;

                double b1r = (bReal[i] + bReal[j]) / 2;
                double b1i = (bImag[i] - bImag[j]) / 2;
                double b2r = (bImag[i] + bImag[j]) / 2;
                double b2i = (bReal[j] - bReal[i]) / 2;

                faReal[i] = a1r * b1r - a1i * b1i - a2r * b2i - a2i * b2r;
                faImag[i] = a1r * b1i + a1i * b1r + a2r * b2r - a2i * b2i;

                fbReal[i] = a1r * b2r - a1i * b2i + a2r * b1r - a2i * b1i;
                fbImag[i] = a1r * b2i + a1i * b2r + a2r * b1i + a2i * b1r;
            }

            idft(new double[][]{faReal, faImag}, CachedLog2.floorLog(n));
            idft(new double[][]{fbReal, fbImag}, CachedLog2.floorLog(n));
            int[] res = new int[need];
            for (int i = 0; i < need; i++) {
                long aa = (long) (faReal[i] + 0.5);
                long bb = (long) (fbReal[i] + 0.5);
                long cc = (long) (faImag[i] + 0.5);
                res[i] = (int) ((aa % m + (bb % m << 15) + (cc % m << 30)) % m);
            }
            return res;
        }

    }

    static class CachedPow {
        private int[] first;
        private int[] second;
        private Modular mod;
        private Modular powMod;

        public CachedPow(int x, Modular mod) {
            this(x, mod.getMod(), mod);
        }

        public CachedPow(int x, int maxExp, Modular mod) {
            this.mod = mod;
            this.powMod = mod.getModularForPowerComputation();
            int k = Math.max(1, (int) DigitUtils.round(Math.sqrt(maxExp)));
            first = new int[k];
            second = new int[maxExp / k + 1];
            first[0] = 1;
            for (int i = 1; i < k; i++) {
                first[i] = mod.mul(x, first[i - 1]);
            }
            second[0] = 1;
            int step = mod.mul(x, first[k - 1]);
            for (int i = 1; i < second.length; i++) {
                second[i] = mod.mul(second[i - 1], step);
            }
        }

        public int pow(int exp) {
            return mod.mul(first[exp % first.length], second[exp / first.length]);
        }

        public int inverse(int exp) {
            return pow(powMod.valueOf(-exp));
        }

    }

    static class BinomialComposite {
        private int m;
        private Modular mod;
        private IntegerList composites;

        public BinomialComposite(long n, int m, Modular mod) {
            this.m = m;
            this.mod = mod;
            composites = pow(n);
            composites.expandWith(0, m + 1);
        }

        public int get(int i) {
            return composites.get(i);
        }

        private void mul(IntegerList a, IntegerList b, IntegerList c) {
            Polynomials.mul(a, b, c, mod);
            trim(c);
        }

        private void trim(IntegerList x) {
            if (x.size() > m + 1) {
                x.remove(m + 1, x.size() - 1);
            }
        }

        private void mul(IntegerList p, IntegerList ans) {
            ans.clear();
            ans.expandWith(0, p.size() + 1);

            int n = p.size();
            for (int i = 0; i < n; i++) {
                int val = p.get(i);
                ans.set(i, mod.plus(ans.get(i), val));
                ans.set(i + 1, val);
            }

            trim(ans);
        }

        private IntegerList pow(long exp) {
            int ceil = CachedLog2.ceilLog(m + 1 + m);
            Loop<IntegerList> loop = new Loop<>(new IntegerList(1 << ceil), new IntegerList(1 << ceil));
            loop.get().add(1);
            for (int i = CachedLog2.floorLog(exp); i >= 0; i--) {
                mul(loop.get(), loop.get(), loop.turn());
                if (1 == Bits.bitAt(exp, i)) {
                    mul(loop.get(), loop.turn());
                }
            }
            return loop.get();
        }

    }

    static class Factorial {
        int[] fact;
        int[] inv;
        Modular modular;

        public Modular getModular() {
            return modular;
        }

        public Factorial(int[] fact, int[] inv, InverseNumber in, int limit, Modular modular) {
            this.modular = modular;
            this.fact = fact;
            this.inv = inv;
            fact[0] = inv[0] = 1;
            for (int i = 1; i <= limit; i++) {
                fact[i] = modular.mul(fact[i - 1], i);
                inv[i] = modular.mul(inv[i - 1], in.inv[i]);
            }
        }

        public Factorial(int limit, Modular modular) {
            this(new int[limit + 1], new int[limit + 1], new InverseNumber(limit, modular), limit, modular);
        }

        public int fact(int n) {
            return fact[n];
        }

        public int invFact(int n) {
            return inv[n];
        }

    }

    static class Composite {
        final Factorial factorial;
        final Modular modular;

        public Composite(Factorial factorial) {
            this.factorial = factorial;
            this.modular = factorial.getModular();
        }

        public Composite(int limit, Modular modular) {
            this(new Factorial(limit, modular));
        }

        public int composite(int m, int n) {
            if (n > m) {
                return 0;
            }
            return modular.mul(modular.mul(factorial.fact(m), factorial.invFact(n)), factorial.invFact(m - n));
        }

    }

    static class CachedLog2 {
        private static final int BITS = 16;
        private static final int LIMIT = 1 << BITS;
        private static final byte[] CACHE = new byte[LIMIT];

        static {
            int b = 0;
            for (int i = 0; i < LIMIT; i++) {
                while ((1 << (b + 1)) <= i) {
                    b++;
                }
                CACHE[i] = (byte) b;
            }
        }

        public static int ceilLog(int x) {
            int ans = floorLog(x);
            if ((1 << ans) < x) {
                ans++;
            }
            return ans;
        }

        public static int floorLog(int x) {
            return x < LIMIT ? CACHE[x] : (BITS + CACHE[x >>> BITS]);
        }

        public static int floorLog(long x) {
            int ans = 0;
            while (x >= LIMIT) {
                ans += BITS;
                x >>>= BITS;
            }
            return ans + CACHE[(int) x];
        }

    }

    static class InverseNumber {
        int[] inv;

        public InverseNumber(int[] inv, int limit, Modular modular) {
            this.inv = inv;
            inv[1] = 1;
            int p = modular.getMod();
            for (int i = 2; i <= limit; i++) {
                int k = p / i;
                int r = p % i;
                inv[i] = modular.mul(-k, inv[r]);
            }
        }

        public InverseNumber(int limit, Modular modular) {
            this(new int[limit + 1], limit, modular);
        }

    }

    static class SequenceUtils {
        public static void swap(double[] data, int i, int j) {
            double tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }

        public static boolean equal(int[] a, int al, int ar, int[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

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

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

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

        public FastOutput println(int c) {
            cache.append(c).append('\n');
            return this;
        }

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

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

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

    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public int valueOf(int x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return x;
        }

        public int valueOf(long x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return (int) x;
        }

        public int mul(int x, int y) {
            return valueOf((long) x * y);
        }

        public int plus(int x, int y) {
            return valueOf(x + y);
        }

        public Modular getModularForPowerComputation() {
            return new Modular(m - 1);
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static class Power {
        final Modular modular;

        public Power(Modular modular) {
            this.modular = modular;
        }

        public int pow(int x, int n) {
            if (n == 0) {
                return modular.valueOf(1);
            }
            long r = pow(x, n >> 1);
            r = modular.valueOf(r * r);
            if ((n & 1) == 1) {
                r = modular.valueOf(r * x);
            }
            return (int) r;
        }

    }

    static class Loop<T> {
        T[] data;
        int pos;

        public Loop(T... data) {
            this.data = data;
        }

        public T turn(int i) {
            pos += i;
            return get(0);
        }

        public T turn() {
            return turn(1);
        }

        public T get(int i) {
            return data[(pos + i) % data.length];
        }

        public T get() {
            return get(0);
        }

    }

    static class Polynomials {
        public static int rankOf(IntegerList p) {
            int[] data = p.getData();
            int r = p.size() - 1;
            while (r >= 0 && data[r] == 0) {
                r--;
            }
            return Math.max(0, r);
        }

        public static void mul(IntegerList a, IntegerList b, IntegerList c, Modular mod) {
            int rA = rankOf(a);
            int rB = rankOf(b);
            c.clear();
            c.expandWith(0, rA + rB + 1);
            if (rA >= 64 && rB >= 64) {
                int[] ans = FastFourierTransform.multiplyMod(a.getData(), rA + 1,
                        b.getData(), rB + 1, mod.getMod());
                c.clear();
                c.addAll(ans);
                return;
            }
            int[] aData = a.getData();
            int[] bData = b.getData();
            int[] cData = c.getData();
            for (int i = 0; i <= rA; i++) {
                for (int j = 0; j <= rB; j++) {
                    cData[i + j] = mod.plus(cData[i + j], mod.mul(aData[i], bData[j]));
                }
            }
        }

    }

    static class Bits {
        private Bits() {
        }

        public static int bitAt(long x, int i) {
            return (int) ((x >> i) & 1);
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static long round(double x) {
            if (x >= 0) {
                return (long) (x + 0.5);
            } else {
                return (long) (x - 0.5);
            }
        }

    }

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

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

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

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

        public int readInt() {
            int sign = 1;

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

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

            return val;
        }

    }
}


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

public class Cards {
    public static long MOD = 998244353;
    public static long[][] stirling;
    public static void main(String[] args) throws IOException{
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        stirling = new long[5001][5001];
        stirling[0][0] = 1;
        for(int i = 1; i < 5001; i++){
            for(int j = 1; j < 5001; j++){
                stirling[i][j] = (stirling[i-1][j-1] % MOD) + (j*stirling[i-1][j]) % MOD;
                stirling[i][j]%=MOD;
            }
        }
        StringTokenizer st = new StringTokenizer(f.readLine());
        long n = Long.parseLong(st.nextToken());
        long m = Long.parseLong(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        long p = modInverse(m, MOD);
        long val = 1;
        long ans = 0;
        long prob = 1;
        for(int i = k; i > 0; i--){
            val*=(n-(k-i));
            val%=MOD;
            prob*=p;
            prob%=MOD;
            ans += (((val*prob)%MOD)*stirling[k][k-i+1])%MOD;
            ans%=MOD;
        }
        System.out.println(ans);

    }

    public static long modInverse(long x, long p){
        return power(x, p-2, p);
    }

    public static long power(long x, long y, long p){
        long res = 1;
        x = x % p;

        while (y > 0) {

            if (y % 2 == 1)
                res = (res * x) % p;

            y = y >> 1;
            x = (x * x) % p;
        }

        return res;
    }

}


import java.util.*;

public class Main
{
    public static final long MOD=998244353;
    static long add(long x, long y) {
        return ((x+y)%MOD+MOD)%MOD;
    }
    static long mult(long x, long y) {
        return ((x*y*1L)%MOD+MOD)%MOD;
    }
    static long exp(long x, long y) {
        if(y==0) return 1;
        else {
            long k = exp(x, y/2);
            if(y%2==0) return mult(k, k);
            else return mult(mult(k, k), x);
        }
    }
    static long inv(long x) {
        return exp(x, MOD-2);
    }

	public static void main(String[] args) {
	    //f you CollegeBoard for making me write in Java
	    Scanner sc = new Scanner(System.in);
	    long n = sc.nextLong();
	    long m = sc.nextLong();
	    int k = sc.nextInt();
	    long[][] dp = new long[k+1][k+1];
	    dp[0][0]=1;
	    for(int i=0; i<k; i++) {
		    for(int j=0; j<k; j++) {
			    dp[i+1][j] = add(dp[i+1][j], mult(dp[i][j], j));
			    dp[i+1][j+1] = add(dp[i+1][j+1], mult(dp[i][j], n-j));
		    }
	    }
	    long ans=0;
	    for(int i=1; i<=k; i++) ans=add(ans, mult(dp[k][i], exp(inv(m), i)));
	    System.out.println(ans);
	}
}


//package com.company;

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

public class Main {
    public static class Task {
        int mod = 998244353;
        int add(int a, int b) {
            int c = a + b;
            if (c >= mod) return c - mod;
            if (c < 0) return  c+ mod;
            return c;
        }
        int mult(int a, int b) {
            return (int) ((long) a * b % mod);
        }
        int mult(int... x) {
            int r = 1;
            for (int y: x) {
                r = mult(r, y);
            }
            return r;
        }
        int[][] stirling;
        void pre() {
            stirling = new int[5001][5001];
            for (int i = 0; i < stirling.length; i++) {
                stirling[i][0] = stirling[0][1] = 0;
            }
            for (int i = 0; i < stirling.length; i++) {
                stirling[i][i] = 1;
            }
            for (int i = 2; i < stirling.length; i++) {
                for (int j = 1; j < i; j++) {
                    stirling[i][j] = add(mult(stirling[i - 1][j], i - 1), stirling[i - 1][j - 1]);
                }
            }
//            System.err.println(Arrays.toString(Arrays.copyOf(stirling[0], 4)));
//            System.err.println(Arrays.toString(Arrays.copyOf(stirling[1], 4)));
//            System.err.println(Arrays.toString(Arrays.copyOf(stirling[2], 4)));
//            System.err.println(Arrays.toString(Arrays.copyOf(stirling[3], 4)));
        }

        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            pre();
            int n = sc.nextInt();
            int m = sc.nextInt();
            int k = sc.nextInt();
            int invm = (int)BigInteger.valueOf(m).modInverse(BigInteger.valueOf(mod)).longValue(); //inv(m);
            int[] pVal = new int[5001];
            pVal[0] = 1;
            int md = n;
            int prp = 1;
            for (int i = 1; i <= k; i++) {
                prp = mult(prp, md, invm);
                md = add(md, -1);
                int sub = prp;
                for (int j = i - 1; j >= 1; j--) {
                    sub = add(sub, mult(stirling[i][j], ((i - j) % 2 == 1) ? pVal[j]: add(0, -pVal[j])));
                }
                pVal[i] = sub;
            }
            pw.println(pVal[k]);
        }

    }

    static long TIME_START, TIME_END;

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("input_line"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("input_line"));

        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
        System.err.println("Memory increased: " + (usedMemoryAfter - usedMemoryBefore) / 1000000);
        System.err.println("Time used: " + (TIME_END - TIME_START) + ".");
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

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

        public Scanner(FileReader s) throws FileNotFoundException {
            br = new BufferedReader(s);
        }

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

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

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

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

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

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


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

public class E implements Runnable{
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int MOD = 998244353;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("Go!");

		int n = fs.nextInt();
		int k = fs.nextInt();
		if(Math.min(n, k) == 1) {
			System.out.println(0);
			return;
		}

		int[] prefDP = new int[n + 1];
		int[] dp = new int[n + 1];
		for(int len = 1; len <= n; len++) {
			int[] dp2 = new int[n + 1];
			int sum = 0;
			for(int i = 1; i <= n; i++) {
				if(i <= len) {
					dp2[i] = add(sum, 1);
				}
				else {
					sum = sub(sum, dp2[i-len-1]);
					dp2[i] = sum;
				}
				sum = add(sum, dp2[i]);
			}
			prefDP[len] = dp2[n];
			dp[len] = sub(prefDP[len], prefDP[len-1]);
		}

		int res = 0;
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				if(i * j < k) {
					res = add(res, mult(dp[i], dp[j]));
				}

		res = mult(res, 2);
		out.println(res);
		out.close();
	}

	int mult(int a, int b) {
		long c = a % MOD;
		c *= b%MOD;
		return (int)(c % MOD);
	}

	int sub(int a, int b) {
		return ((a%MOD) - (b%MOD) + MOD) % MOD;
	}

	int add(int a, int b) {
		return ((a%MOD) + (b%MOD))%MOD;
	}

	void sort (int[] a) {
		int n = a.length;
		for(int i = 0; i < 50; i++) {
			Random r = new Random();
			int x = r.nextInt(n), y = r.nextInt(n);
			int temp = a[x];
			a[x] = a[y];
			a[y] = temp;
		}
		Arrays.sort(a);
	}

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

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

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

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

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

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

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

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

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

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

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


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

public class G {

	void submit() {
		int n = nextInt();
		int k = nextInt();
		int s = nextInt() - 1;
		long t = nextLong();
		out.println(solve(n, k, s, t) + 1);
	}

	int solve(int n, int k, int s, long t) {
		// int n = nextInt();
		// int k = nextInt();
		// int s = nextInt() - 1;
		// long t = nextLong();
		while (t % n != 0) {
			int delta = (int) ((s < k ? 1 : -1) * (t % n));
			s = (s + n + delta) % n;
			t--;
		}

		t /= n;

		long[] when = new long[n];
		Arrays.fill(when, -1);

		for (long left = t; left > 0; left--) {
			if (when[s] != -1) {
				long period = when[s] - left;

				for (int i = 0; i < n; i++) {
					if (when[i] != -1 && when[i] <= when[s]
							&& when[i] % period == 0) {
						// out.println(i + 1);
						return i;
					}
				}

				throw new AssertionError();

			}
			when[s] = left;

			for (int i = n - 1; i > 0; i--) {
				if (s < k) {
					s += i;
					if (s >= n) {
						s -= n;
					}
				} else {
					s -= i;
					if (s < 0) {
						s += n;
					}
				}
			}

		}

		// out.println(s + 1);
		return s;

	}

	int go(int n, int m) {
		int[] a = IntStream.range(0, n).toArray();
		for (int i = n - 1; i > 0; i--) {
			for (int j = 0; j < n; j++) {
				int delta = a[j] < m ? 1 : -1;
				a[j] = (a[j] + n + i * delta) % n;
			}
		}
		// System.err.println(Arrays.toString(a));
		// out.println("digraph G {");
		// for (int i = 0; i < n; i++) {
		// out.println(i + " -> " + a[i] + ";");
		// }
		// out.println("}");

		return maxDepth(a);
	}

	int maxDepth(int[] p) {
		int n = p.length;
		int[] used = new int[n];
		int ret = 0;
		Arrays.fill(used, -1);
		for (int i = 0; i < n; i++) {
			int cur = 0;
			int v = i;
			while (used[v] != i) {
				used[v] = i;
				cur++;
				v = p[v];
			}
			ret = Math.max(ret, cur);
		}
		return ret;
	}

	void test() {
		/*
		 * int max = -1; for (int n = 1;; n <<= 1) { // if (n % 40 == 0) {
		 * System.err.println(n); // } for (int k = 1; k < Math.min(n, 20); k++)
		 * { int tmp = go(n, k); if (tmp > max) { max = tmp;
		 * System.err.println(max + " @ " + n + " " + k); } } }
		 */
		for (int s = 0; s < 65536; s++) {
			System.err.println(solve(65536, 1, s, 1_000_000_000_000L));
		}
	}

	void stress() {
		for (int tst = 0;; tst++) {
			if (false) {
				throw new AssertionError();
			}
			System.err.println(tst);
		}
	}

	G() throws IOException {
		is = System.in;
		out = new PrintWriter(System.out);
		submit();
		// stress();
		// test();
		out.close();
	}

	static final Random rng = new Random();
	static final int C = 5;

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

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

	private InputStream is;
	PrintWriter out;

	private byte[] buf = new byte[1 << 14];
	private int bufSz = 0, bufPtr = 0;

	private int readByte() {
		if (bufSz == -1)
			throw new RuntimeException("Reading past EOF");
		if (bufPtr >= bufSz) {
			bufPtr = 0;
			try {
				bufSz = is.read(buf);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			if (bufSz <= 0)
				return -1;
		}
		return buf[bufPtr++];
	}

	private boolean isTrash(int c) {
		return c < 33 || c > 126;
	}

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

	String nextToken() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	String nextString() {
		int b = readByte();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b) || b == ' ') {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	char nextChar() {
		return (char) skip();
	}

	int nextInt() {
		int ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}

	long nextLong() {
		long ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}
}


import java.util.*;
public class TakeMetro {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int M = scanner.nextInt();
        //saves mod annoyances
        int S = scanner.nextInt()-1;
        long T = scanner.nextLong();
        while (T%N!=0) {
            if (S < M) {
                S = (int)((S + T) % N);
            } else {
                S = (int)((((S - T) % N) + N ) % N);
            }
            T--;
        }
        T /= N;
        //periodically shows up at same station, though not sure where yet
        int[] last = new int[N];
        Arrays.fill(last, -1);
        int cur = 0;
        //saw ourselves at the 0th round of N train takes
        last[S] = cur;
        while(T-- > 0) {
            for(int i = N-1; i > 0; i--) {
                if (S < M) {
                    S = (S + i) % N;
                } else {
                    S = (((S - i) % N) + N) % N;
                }
            }
            cur++;
            if (last[S] != -1) {
                T = T%(cur-last[S]);
                last[S] = cur;
            }
            else {
                last[S] = cur;
            }
        }
        System.out.println((S+1));
    }
}


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

public class G {

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int s = sc.nextInt() - 1;
		long t = sc.nextLong();
		int[] next = new int[n];
		Arrays.fill(next, -1);
		while (t % n != 0) {
			if (s < m) s += t % n;
			else s += n - t % n;
			s %= n;
			t--;
		}
		long cant = t / n;
		int prevs = s;
		while (cant > 0 && next[s] == -1) {
			for (int i = n - 1; i > 0; i--) {
				if (s < m) s += i;
				else s += n - i;
				if (s >= n) s -= n;
			}
			next[prevs] = s;
			prevs = s;
			cant--;
		}
		if (cant > 0) {
			long cicle = 1;
			prevs = s;
			while (next[prevs] != s) {
				cicle++;
				prevs = next[prevs];
			}
			long total = cant % cicle;
			for (int i = 0; i < total; i++) {
				s = next[s];
			}
		}
		out.println(s+1);

		out.flush();
	}

	static class MyScanner {
		private BufferedReader br;
		private StringTokenizer tokenizer;

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

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

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

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


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author kessido
 */
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);
        GTakeMetro solver = new GTakeMetro();
        solver.solve(1, in, out);
        out.close();
    }

    static class GTakeMetro {
        int n;
        int m;
        int s;
        long t;

        void step() {
            int curJump = (int) ((t--) % n);
            int sign = s < m ? 1 : -1;
            s += sign * curJump;
            s %= n;
            if (s < 0) s += n;
        }

        void doLoop() {
            for (int i = 0; i < n; i++) step();
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            n = in.NextInt();
            m = in.NextInt();
            s = in.NextInt() - 1;
            t = in.NextLong();

            while ((t % n) != 0) step();

            long[] lastSeem = new long[n];
            Arrays.fill(lastSeem, -1);
            while (t != 0) {
                doLoop();
                if (lastSeem[s] != -1) {
                    long interval = lastSeem[s] - t;
                    t %= interval;
                    break;
                } else {
                    lastSeem[s] = t;
                }
            }
            while (t != 0) step();
            out.println(s + 1);
        }

    }

    static class InputReader {
        BufferedReader reader;
        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(), " \t\n\r\f,");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

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

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

    }
}


import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.max;
import static java.lang.System.arraycopy;
import static java.lang.System.exit;
import static java.util.Arrays.copyOf;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

public class G {

	static class IntList {

		int data[] = new int[3];
		int size = 0;

		boolean isEmpty() {
			return size == 0;
		}

		int size() {
			return size;
		}

		int get(int index) {
			if (index < 0 || index >= size) {
				throw new IndexOutOfBoundsException();
			}
			return data[index];
		}

		void clear() {
			size = 0;
		}

		void set(int index, int value) {
			if (index < 0 || index >= size) {
				throw new IndexOutOfBoundsException();
			}
			data[index] = value;
		}

		void expand() {
			if (size >= data.length) {
				data = copyOf(data, (data.length << 1) + 1);
			}
		}

		void insert(int index, int value) {
			if (index < 0 || index > size) {
				throw new IndexOutOfBoundsException();
			}
			expand();
			arraycopy(data, index, data, index + 1, size++ - index);
			data[index] = value;
		}

		int delete(int index) {
			if (index < 0 || index >= size) {
				throw new IndexOutOfBoundsException();
			}
			int value = data[index];
			arraycopy(data, index + 1, data, index, --size - index);
			return value;
		}

		void push(int value) {
			expand();
			data[size++] = value;
		}

		int pop() {
			if (size == 0) {
				throw new NoSuchElementException();
			}
			return data[--size];
		}

		void unshift(int value) {
			expand();
			arraycopy(data, 0, data, 1, size++);
			data[0] = value;
		}

		int shift() {
			if (size == 0) {
				throw new NoSuchElementException();
			}
			int value = data[0];
			arraycopy(data, 1, data, 0, --size);
			return value;
		}
	}

	static class IntIntMap {

		static final int EMPTY = Integer.MIN_VALUE;

		int data[] = new int[4];
		{
			data[0] = EMPTY;
			data[2] = EMPTY;
		}
		int size = 0;

		boolean isEmpty() {
			return size == 0;
		}

		int size() {
			return size;
		}

		void clear() {
			for (int i = 0; i < data.length; i += 2) {
				data[i] = EMPTY;
			}
			size = 0;
		}

		static int hash(int key) {
			int hash = key * 1000000007;
			hash ^= hash >> 16;
			hash ^= hash >> 24;
			return hash;
		}

		boolean have(int key) {
			if (key == EMPTY) {
				throw new IllegalArgumentException();
			}
			for (int mask = data.length - 2, i = hash(key) & mask;; i = (i - 1) & mask) {
				int cur = data[i];
				if (cur == key) {
					return true;
				} else if (cur == EMPTY) {
					return false;
				}
			}
		}

		int get(int key, int default_) {
			if (key == EMPTY) {
				throw new IllegalArgumentException();
			}
			for (int mask = data.length - 2, i = hash(key) & mask;; i = (i - 1) & mask) {
				int cur = data[i];
				if (cur == key) {
					return data[i + 1];
				} else if (cur == EMPTY) {
					return default_;
				}
			}
		}

		static int[] resize(int data[], int newCapacity) {
			int oldCapacity = data.length;
			int ndata[] = new int[newCapacity];
			for (int i = 0; i < newCapacity; i += 2) {
				ndata[i] = EMPTY;
			}
			for (int mask = newCapacity - 2, i = 0; i < oldCapacity; i += 2) {
				int cur = data[i];
				if (cur == EMPTY) {
					continue;
				}
				for (int j = hash(cur) & mask;; j = (j - 1) & mask) {
					if (ndata[j] == EMPTY) {
						ndata[j] = cur;
						ndata[j + 1] = data[i + 1];
						break;
					}
				}
			}
			return ndata;
		}

		void set(int key, int value) {
			if (key == EMPTY) {
				throw new IllegalArgumentException();
			}
			int data[] = this.data;
			for (int capacity = data.length, mask = capacity - 2, i = hash(key) & mask;; i = (i - 1) & mask) {
				int cur = data[i];
				if (cur == key) {
					data[i + 1] = value;
					return;
				} else if (cur == EMPTY) {
					data[i] = key;
					data[i + 1] = value;
					if (++size > capacity >> 2) {
						this.data = resize(data, capacity << 1);
					}
					return;
				}
			}
		}

		void delete(int key) {
			if (key == EMPTY) {
				throw new IllegalArgumentException();
			}
			int data[] = this.data;
			for (int capacity = data.length, mask = capacity - 2, i = hash(key) & mask;; i = (i - 1) & mask) {
				int cur = data[i];
				if (cur == key) {
					for (int j = i;;) {
						cur = data[j = (j - 1) & mask];
						if (cur == EMPTY) {
							data[i] = EMPTY;
							--size;
							return;
						}
						int k = hash(cur) & mask;
						if ((k >= i) ^ (k < j) ^ (i < j)) {
							data[i] = cur;
							data[i + 1] = data[j + 1];
							i = j;
						}
					}
				} else if (cur == EMPTY) {
					return;
				}
			}
		}

		void expand(int newCapacity) {
			int data[] = this.data;
			int oldCapacity = data.length;
			if (oldCapacity >> 2 < newCapacity) {
				this.data = resize(data, Integer.highestOneBit(newCapacity - 1) << 3);
			}
		}

		void shrink() {
			int data[] = this.data;
			int oldCapacity = data.length;
			if (oldCapacity > 4 && oldCapacity >> 3 >= size) {
				this.data = resize(data, max(Integer.highestOneBit(size - 1) << 3, 4));
			}
		}

		static class Iterator {

			final int data[];
			int position = -2;

			Iterator(int data[]) {
				this.data = data;
				advance();
			}

			boolean hasNext() {
				return position < data.length;
			}

			int getKey() {
				return data[position];
			}

			int getValue() {
				return data[position + 1];
			}

			void advance() {
				do {
					position += 2;
				} while (position < data.length && data[position] == EMPTY);
			}
		}

		Iterator iterator() {
			return new Iterator(data);
		}
	}

	static final List<IntList> freeLists = new ArrayList<>();

	static IntList takeList() {
		if (freeLists.isEmpty()) {
			return new IntList();
		} else {
			return freeLists.remove(freeLists.size() - 1);
		}
	}

	static void putList(IntList list) {
		list.clear();
		freeLists.add(list);
	}

	static int n, m;

	static IntList solve(int from, int to) {
		IntList res;
		if (from + 1 == to) {
			res = takeList();
			res.push(from);
			if (from + m > n) {
				res.push(n - from);
				res.push(from - n);
			}
			res.push(m);
			if (from > m) {
				res.push(n - from);
				res.push(from);
			}
			res.push(-from);
		} else {
			int mid = (from + to) >> 1;
			IntList a = solve(from, mid), b = solve(mid, to);
			res = takeList();
			int aSize = a.size, bSize = b.size;
			int aData[] = a.data, bData[] = b.data;
			for (int i = 0;; i += 2) {
				int bFrom = i == 0 ? 0 : bData[i - 1];
				int bTo = i == bSize - 1 ? n : bData[i + 1];
				int bShift = bData[i];
				int aFrom = bFrom + bShift;
				int aTo = bTo + bShift;
				int l = 0, r = aSize - 1;
				while (l < r) {
					int m = (((l + r) >> 2) << 1) + 1;
					if (aData[m] <= aFrom) {
						l = m + 1;
					} else {
						r = m - 1;
					}
				}
				int cur = l;
				while (true) {
					res.push(bShift + aData[cur]);
					++cur;
					if (cur == aSize) {
						break;
					}
					int pos = aData[cur];
					if (pos >= aTo) {
						break;
					}
					res.push(pos - bShift);
					++cur;
				}
				if (i == bSize - 1) {
					break;
				}
				res.push(bTo);
			}
			putList(a);
			putList(b);
		}
		return res;
	}

	static void solve() throws Exception {
		n = scanInt();
		m = scanInt();
		int s = scanInt() - 1;
		long t = scanLong();
		for (int ct = (int) (t % n); ct != 0; ct--) {
			if (s < m) {
				s += ct;
				if (s >= n) {
					s -= n;
				}
			} else {
				s -= ct;
				if (s < 0) {
					s += n;
				}
			}
		}
		long cycles = t / n;
		if (cycles > 0) {
			IntList cycleSolve = solve(0, n);
			int csSize = cycleSolve.size, csData[] = cycleSolve.data;
			IntList cycleList = takeList();
			IntIntMap cycleMap = new IntIntMap();
			for (int it = 0;; it++) {
				if (it == cycles) {
					break;
				}
				int prev = cycleMap.get(s, -1);
				if (prev >= 0) {
					s = cycleList.get(prev + (int) ((cycles - prev) % (it - prev)));
					break;
				}
				cycleList.push(s);
				cycleMap.set(s, it);
				int l = 0, r = csSize - 1;
				while (l < r) {
					int m = (((l + r) >> 2) << 1) + 1;
					if (csData[m] <= s) {
						l = m + 1;
					} else {
						r = m - 1;
					}
				}
				s += csData[l];
			}
		}
		out.print(s + 1);
	}

	static int scanInt() throws IOException {
		return parseInt(scanString());
	}

	static long scanLong() throws IOException {
		return parseLong(scanString());
	}

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

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.TreeSet;
import java.util.ArrayList;
import java.util.List;
import java.util.AbstractCollection;
import java.util.TreeMap;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.util.Collections;
import java.io.InputStream;

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

    static class TaskC {
        final double eps = 1e-8;

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            Circle[] circles = new Circle[n];
            for (int i = 0; i < n; i++) {
                int x = in.nextInt();
                int y = in.nextInt();
                int r = in.nextInt();
                circles[i] = new Circle();
                circles[i].o = new Point(x, y);
                circles[i].r = r;
            }

            Set<Point> all = new TreeSet<>();
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    List<Point> inter = intersect(circles[i], circles[j]);
                    if (inter == null) {
                        continue;
                    }
                    all.addAll(inter);
                }
            }

            Map<Point, Integer> pointId = new TreeMap<>();
            List<Set<Integer>> adj = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                List<Double> angles = new ArrayList<>();
                final int K = 100;
                for (int j = 0; j < K; j++) {
                    angles.add(Math.PI * 2 * j / K);
                }
                for (Point p : all) {
                    if (circles[i].contains(p)) {
                        double dx = p.x - circles[i].o.x;
                        double dy = p.y - circles[i].o.y;
                        double alpha = Math.atan2(dy, dx);
                        if (alpha < 0) {
                            alpha += 2 * Math.PI;
                        }
                        angles.add(alpha);
                    }
                }
                Collections.sort(angles);
                Point dir = new Point(1, 0).scale(circles[i].r);
                Double[] as = new TreeSet<>(angles).toArray(new Double[0]);
                for (int j = 0; j < as.length; j++) {
                    Point p = circles[i].o.add(dir.rotate(as[j]));
                    getId(p, pointId, adj);
                }
                for (int j = 0; j < as.length; j++) {
                    Point p = circles[i].o.add(dir.rotate(as[j]));
                    Point q = circles[i].o.add(dir.rotate(as[(j + 1) % as.length]));
                    int u = pointId.get(p);
                    int v = pointId.get(q);
                    if (u == v) {
                        continue;
                    }
                    adj.get(u).add(v);
                    adj.get(v).add(u);
                }
            }

            int v = adj.size();
            int e = 0;
            for (int i = 0; i < v; i++) {
                e += adj.get(i).size();
            }
            e /= 2;

            int comps = 0;
            boolean[] was = new boolean[v];
            for (int i = 0; i < v; i++) {
                if (!was[i]) {
                    ++comps;
                    dfs(i, was, adj);
                }
            }

            out.println(1 + comps + e - v);
        }

        private void dfs(int i, boolean[] was, List<Set<Integer>> adj) {
            was[i] = true;
            for (int j : adj.get(i)) {
                if (!was[j]) {
                    dfs(j, was, adj);
                }
            }
        }

        private void getId(Point p, Map<Point, Integer> pointId, List<Set<Integer>> adj) {
            if (!pointId.containsKey(p)) {
                int sz = pointId.size();
                pointId.put(p, sz);
                adj.add(new TreeSet<>());
            }
        }

        private List<Point> intersect(Circle c1, Circle c2) {
            double dx = c1.o.x - c2.o.x;
            double dy = c1.o.y - c2.o.y;
            double d = Math.sqrt(dx * dx + dy * dy);
            double cos = (c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d);
            if (cos < -1 - eps) {
                return null;
            }
            if (cos < -1) {
                cos = -1;
            }
            if (cos > 1 + eps) {
                return null;
            }
            if (cos > 1) {
                cos = 1;
            }
            List<Point> res = new ArrayList<>();
            double alpha = Math.acos(cos);
            Point dir = c2.o.sub(c1.o).norm();
            res.add(c1.o.add(dir.scale(c1.r).rotate(+alpha)));
            res.add(c1.o.add(dir.scale(c1.r).rotate(-alpha)));
            return res;
        }

        class Point implements Comparable<Point> {
            double x;
            double y;

            Point(double x, double y) {
                this.x = x;
                this.y = y;
            }

            Point add(Point o) {
                return new Point(x + o.x, y + o.y);
            }

            Point sub(Point o) {
                return new Point(x - o.x, y - o.y);
            }

            Point rotate(double alpha) {
                double c = Math.cos(alpha);
                double s = Math.sin(alpha);
                double nx = x * c - y * s;
                double ny = x * s + y * c;
                return new Point(nx, ny);
            }

            Point norm() {
                double len = length();
                return scale(1.0 / len);
            }

            Point scale(double f) {
                return new Point(f * x, f * y);
            }

            double length() {
                return Math.sqrt(x * x + y * y);
            }

            public String toString() {
                return String.format("%.6f %.6f", x, y);
            }

            public boolean equals(Object obj) {
                Point o = (Point) obj;
                return Math.abs(x - o.x) < eps && Math.abs(y - o.y) < eps;
            }

            public int compareTo(Point o) {
                if (Math.abs(x - o.x) > eps) {
                    return x < o.x ? -1 : 1;
                }
                if (Math.abs(y - o.y) > eps) {
                    return y < o.y ? -1 : 1;
                }
                return 0;
            }

        }

        class Circle {
            Point o;
            double r;

            boolean contains(Point p) {
                double dist = p.sub(o).length();
                return Math.abs(dist - r) < eps;
            }

        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

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

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

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.stream.IntStream;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Andy Phan
 */
public class c {

    public static void main(String[] args) {
        FS in = new FS(System.in);
        int n = in.nextInt();
        Circle[] circ = new Circle[n];
        for(int i = 0; i < n; i++) {
            circ[i] = new Circle(new Vec(in.nextInt(), in.nextInt()), in.nextInt());
        }
        ArrayList<Vec> points = new ArrayList<>();
        int[] par = new int[n];
        Arrays.setAll(par, i -> i);
        int res = 1;
        for(int i = 0; i < n; i++) {
            ArrayList<Vec> points2 = new ArrayList<>();
            for(int j = 0; j < n; j++) {
                if(i == j) continue;
                Vec[] arr = circ[i].intersect(circ[j]);
                if(arr == null) continue;
                int a = par[i] = par[par[i]];
                int b = par[j] = par[par[j]];
                par[a] = b;
                outer: for(Vec e : arr) {
                    for(Vec e2 : points2) {
                        if(e.equals(e2)) continue outer;
                    }
                    points2.add(e);
                }
            }
            res += points2.size();
            outer: for(Vec e : points2) {
                for(Vec e2 : points) {
                    if(e.equals(e2)) continue outer;
                }
                points.add(e);
            }
        }
        res -= points.size();
        res += IntStream.range(0, n).map(i -> 1-Math.abs(Integer.signum(i-par[i]))).sum();
        System.out.println(res);
    }

    static class Circle {
	Vec c;
	double r;

	public Circle(Vec c, double r) {
		this.c=c;
		this.r=r;
	}

	public boolean contains(Vec v) {
            return c.sub(v).mag2()-Vec.EPS*Vec.EPS<=r*r;
	}

	//when standing at this circle, returns right tangent, then left tangent
	public Vec[] intersect(Circle o) {
            if (c.equals(o.c)) return null;
            Vec dir=o.c.sub(c);
            double d2=dir.mag2(), d=Math.sqrt(d2);
            if (r+o.r<d||r+d<o.r||o.r+d<r)
                    return null;

            if (Vec.eq(r+o.r, d)||Vec.eq(o.r+d, r))
                return new Vec[] {c.add(dir.scale(r/d))};
            if (Vec.eq(r+d, o.r))
                return new Vec[] {c.sub(dir.scale(r/d))};

            double d1=(r*r+d2-o.r*o.r)/(2*d);
            double h=Math.sqrt(r*r-d1*d1);
            Vec unitDir=dir.unit();
            Vec rInt=c.add(unitDir.scale(d1).add(unitDir.rot270().scale(h)));
            Vec lInt=c.add(unitDir.scale(d1).add(unitDir.rot90().scale(h)));
            return new Vec[] {rInt, lInt};
	}
    }

    static class Vec {
        static final double EPS = 1e-9;

	double x, y;
	public Vec(double x, double y) {this.x=x;this.y=y;}
	public Vec add(Vec o) {return new Vec(x+o.x, y+o.y);}
	public Vec sub(Vec o) {return new Vec(x-o.x, y-o.y);}
	public Vec scale(double s) {return new Vec(x*s, y*s);}
	public double dot(Vec o) {return x*o.x+y*o.y;}
	public double cross(Vec o) {return x*o.y-y*o.x;}
	public double mag2() {return dot(this);}
	public double mag() {return Math.sqrt(mag2());}
	public Vec unit() {return scale(1/mag());}
	public Vec rot90() {return new Vec(-y, x);}
	public Vec rot270() {return new Vec(y, -x);}

	public Vec rotate(double theta) {
            double PI=Math.PI;
            double newX=x*Math.cos(theta)+y*Math.cos(PI/2+theta);
            double newY=x*Math.sin(theta)+y*Math.sin(PI/2+theta);
            return new Vec(newX, newY);
	}

	//angle between 0 and 2PI
	public double angle() {
            return (Math.atan2(y, x)+2*Math.PI)%(2*Math.PI);
	}

        public String toString() {
            DecimalFormat df=new DecimalFormat("#.##");
            return "("+df.format(x)+", "+df.format(y)+")";
	}

	static boolean eq(double a, double b) {return Math.abs(a-b)<EPS;}
	static boolean leq(double a, double b) {return a-EPS<b;}
	static boolean geq(double a, double b) {return a+EPS>b;}

	public boolean equals(Object oo) {
            Vec o=(Vec)oo;
            return eq(x, o.x)&&eq(y, o.y);
	}
    }

    static class FS {

        BufferedReader in;
        StringTokenizer token;

        public FS(InputStream str) {
            in = new BufferedReader(new InputStreamReader(str));
        }

        public String next() {
            if (token == null || !token.hasMoreElements()) {
                try {
                    token = new StringTokenizer(in.readLine());
                } catch (IOException ex) {
                }
                return next();
            }
            return token.nextToken();
        }

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