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

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

    static class HZSShufflesCards {
        NumberTheory.Mod998 mod = new NumberTheory.Mod998();
        int n;
        int m;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            n = in.nextInt();
            m = in.nextInt();

            mod.fInv(n + m);

            long phaseSize = 1;
            long p = 1;
            for (int i = 0; p != 0; i++) {
                p = mod.mult(p, n - i, mod.smallInv(n + m - i));
                phaseSize = mod.add(phaseSize, p);
            }

            long answer = 0;
            for (int k = 1; k <= n; k++) {
                long term = mod.mult(mod.ncr(n, k), m + k, mod.smallInv(k), phaseSize);

                if (k % 2 == 1)
                    answer = mod.add(answer, term);
                else
                    answer = mod.subtract(answer, term);
            }

            out.println(answer);
        }

    }

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

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

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

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

    }

    static class Util {
        public static void ASSERT(boolean assertion) {
            if (!assertion)
                throw new AssertionError();
        }

        private Util() {
        }

    }

    static class IntStack {
        int[] array;
        int size = 0;

        public IntStack() {
            this(8);
        }

        public IntStack(int capacity) {
            array = new int[capacity];
        }

        public void push(int item) {
            if (size >= array.length)
                array = resize(array);
            array[size++] = item;
        }

        public int size() {
            return size;
        }

        public int get(int i) {
            Util.ASSERT(i < size);
            return array[i];
        }

        private static int[] resize(int[] array) {
            int[] newArray = new int[array.length << 1];
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
        }

        public String toString() {
            int[] trimmed = new int[size];
            System.arraycopy(array, 0, trimmed, 0, size);
            return Arrays.toString(trimmed);
        }

    }

    static class NumberTheory {
        private static void ASSERT(boolean assertion) {
            if (!assertion)
                throw new AssertionError();
        }

        public abstract static class Modulus<M extends NumberTheory.Modulus<M>> {
            final IntStack factorial = new IntStack();
            final IntStack invFactorial = new IntStack();

            public abstract long modulus();

            public Modulus() {
                super();
                factorial.push(1);
                invFactorial.push(1);
            }

            public long fact(int n) {
                while (factorial.size() <= n) {
                    factorial.push((int) mult(factorial.get(factorial.size() - 1), factorial.size()));
                }

                return factorial.get(n);
            }

            public long fInv(int n) {
                int lastKnown = invFactorial.size() - 1;

                if (lastKnown < n) {
                    long[] fInv = new long[n - lastKnown];
                    fInv[0] = inv(fact(n));
                    for (int i = 1; i < fInv.length; i++) {
                        fInv[i] = mult(fInv[i - 1], n - i + 1);
                    }
                    for (int i = fInv.length - 1; i >= 0; i--) {
                        invFactorial.push((int) fInv[i]);
                    }
                }

                return invFactorial.get(n);
            }

            public long ncr(int n, int r) {
                ASSERT(n >= 0);
                if (r < 0 || n < r)
                    return 0;
                return mult(fact(n), mult(fInv(r), fInv(n - r)));
            }

            public long smallInv(int n) {
                return mult(fInv(n), fact(n - 1));
            }

            public long normalize(long x) {
                x %= modulus();
                if (x < 0)
                    x += modulus();
                return x;
            }

            public long add(long a, long b) {
                long v = a + b;
                return v < modulus() ? v : v - modulus();
            }

            public long subtract(long a, long b) {
                long v = a - b;
                return v < 0 ? v + modulus() : v;
            }

            public long mult(long... x) {
                long r = 1;
                for (long i : x)
                    r = mult(r, i);
                return r;
            }

            public long mult(long a, long b) {
                return (a * b) % modulus();
            }

            public long inv(long value) {
                long g = modulus(), x = 0, y = 1;
                for (long r = value; r != 0; ) {
                    long q = g / r;
                    g %= r;

                    long temp = g;
                    g = r;
                    r = temp;

                    x -= q * y;

                    temp = x;
                    x = y;
                    y = temp;
                }

                ASSERT(g == 1);
                ASSERT(y == modulus() || y == -modulus());

                return normalize(x);
            }

        }

        public static class Mod998 extends NumberTheory.Modulus<NumberTheory.Mod998> {
            public long modulus() {
                return 998_244_353L;
            }

        }

    }
}


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

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

    static class HZSShufflesCards {
        NumberTheory.Mod998 mod = new NumberTheory.Mod998();
        int n;
        int m;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            n = in.nextInt();
            m = in.nextInt();

            mod.fInv(n + m);

            long phaseSize = 1;
            long p = 1;
            for (int i = 0; p != 0; i++) {
                p = mod.mult(p, n - i, mod.smallInv(n + m - i));
                phaseSize = mod.add(phaseSize, p);
            }

            long answer = 0;
            for (int k = 1; k <= n; k++) {
                answer = mod.add(answer, mod.mult(mod.paritySign(k + 1), mod.ncr(n, k), m + k, mod.smallInv(k), phaseSize));
            }

            out.println(answer);
        }

    }

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

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

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

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

    }

    static class Util {
        public static void ASSERT(boolean assertion) {
            if (!assertion)
                throw new AssertionError();
        }

        private Util() {
        }

    }

    static class IntStack {
        int[] array;
        int size = 0;

        public IntStack() {
            this(8);
        }

        public IntStack(int capacity) {
            array = new int[capacity];
        }

        public void push(int item) {
            if (size >= array.length)
                array = resize(array);
            array[size++] = item;
        }

        public int size() {
            return size;
        }

        public int get(int i) {
            Util.ASSERT(i < size);
            return array[i];
        }

        private static int[] resize(int[] array) {
            int[] newArray = new int[array.length << 1];
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
        }

        public String toString() {
            int[] trimmed = new int[size];
            System.arraycopy(array, 0, trimmed, 0, size);
            return Arrays.toString(trimmed);
        }

    }

    static class NumberTheory {
        private static void ASSERT(boolean assertion) {
            if (!assertion)
                throw new AssertionError();
        }

        public abstract static class Modulus<M extends NumberTheory.Modulus<M>> {
            final IntStack factorial = new IntStack();
            final IntStack invFactorial = new IntStack();

            public abstract long modulus();

            public Modulus() {
                super();
                factorial.push(1);
                invFactorial.push(1);
            }

            public long fact(int n) {
                while (factorial.size() <= n) {
                    factorial.push((int) mult(factorial.get(factorial.size() - 1), factorial.size()));
                }

                return factorial.get(n);
            }

            public long fInv(int n) {
                int lastKnown = invFactorial.size() - 1;

                if (lastKnown < n) {
                    long[] fInv = new long[n - lastKnown];
                    fInv[0] = inv(fact(n));
                    for (int i = 1; i < fInv.length; i++) {
                        fInv[i] = mult(fInv[i - 1], n - i + 1);
                    }
                    for (int i = fInv.length - 1; i >= 0; i--) {
                        invFactorial.push((int) fInv[i]);
                    }
                }

                return invFactorial.get(n);
            }

            public long paritySign(long k) {
                return (k & 1) == 0 ? 1 : modulus() - 1;
            }

            public long ncr(int n, int r) {
                ASSERT(n >= 0);
                if (r < 0 || n < r)
                    return 0;
                return mult(fact(n), mult(fInv(r), fInv(n - r)));
            }

            public long smallInv(int n) {
                return mult(fInv(n), fact(n - 1));
            }

            public long normalize(long x) {
                x %= modulus();
                if (x < 0)
                    x += modulus();
                return x;
            }

            public long add(long a, long b) {
                long v = a + b;
                return v < modulus() ? v : v - modulus();
            }

            public long mult(long... x) {
                long r = 1;
                for (long i : x)
                    r = mult(r, i);
                return r;
            }

            public long mult(long a, long b) {
                return (a * b) % modulus();
            }

            public long inv(long value) {
                long g = modulus(), x = 0, y = 1;
                for (long r = value; r != 0; ) {
                    long q = g / r;
                    g %= r;

                    long temp = g;
                    g = r;
                    r = temp;

                    x -= q * y;

                    temp = x;
                    x = y;
                    y = temp;
                }

                ASSERT(g == 1);
                ASSERT(y == modulus() || y == -modulus());

                return normalize(x);
            }

        }

        public static class Mod998 extends NumberTheory.Modulus<NumberTheory.Mod998> {
            public long modulus() {
                return 998_244_353L;
            }

        }

    }
}


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

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

    static class HZSShufflesCards {
        NumberTheory.Mod998 mod = new NumberTheory.Mod998();
        int n;
        int m;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            n = in.nextInt();
            m = in.nextInt();

            long phaseSize = 1;
            long p = 1;
            for (int i = 0; p != 0; i++) {
                p = mod.mult(p, n - i, mod.inv(n + m - i));
                phaseSize = mod.add(phaseSize, p);
            }

            long answer = 0;
            for (int k = 1; k <= n; k++) {
                long sign = mod.paritySign(k + 1);
                long numPhases = mod.inv(mod.subtract(1, prNoSpecial(k)));
                long e = mod.mult(numPhases, phaseSize);
                long term = mod.mult(mod.ncr(n, k), e);
                answer = mod.add(answer, mod.mult(sign, term));
            }

            out.println(answer);
        }

        private long prNoSpecial(int k) {
            return mod.div(mod.ncr(m + k - 1, k), mod.ncr(m + k, k));
        }

    }

    static class NumberTheory {
        private static void ASSERT(boolean assertion) {
            if (!assertion)
                throw new AssertionError();
        }

        public abstract static class Modulus<M extends NumberTheory.Modulus<M>> {
            final ArrayList<Long> factorial = new ArrayList<>();
            final ArrayList<Long> invFactorial = new ArrayList<>();

            public abstract long modulus();

            public Modulus() {
                super();
                factorial.add(1L);
                invFactorial.add(1L);
            }

            public long fact(int n) {
                while (factorial.size() <= n) {
                    factorial.add(mult(factorial.get(factorial.size() - 1), factorial.size()));
                }

                return factorial.get(n);
            }

            public long fInv(int n) {
                int lastKnown = invFactorial.size() - 1;

                if (lastKnown < n) {
                    long[] fInv = new long[n - lastKnown];
                    fInv[0] = inv(fact(n));
                    for (int i = 1; i < fInv.length; i++) {
                        fInv[i] = mult(fInv[i - 1], n - i + 1);
                    }
                    for (int i = fInv.length - 1; i >= 0; i--) {
                        invFactorial.add(fInv[i]);
                    }
                }

                return invFactorial.get(n);
            }

            public long paritySign(long k) {
                return (k & 1) == 0 ? 1 : modulus() - 1;
            }

            public long ncr(int n, int r) {
                ASSERT(n >= 0);
                if (r < 0 || n < r)
                    return 0;
                return mult(fact(n), mult(fInv(r), fInv(n - r)));
            }

            public long normalize(long x) {
                x %= modulus();
                if (x < 0)
                    x += modulus();
                return x;
            }

            public long add(long a, long b) {
                long v = a + b;
                return v < modulus() ? v : v - modulus();
            }

            public long subtract(long a, long b) {
                long v = a - b;
                return v < 0 ? v + modulus() : v;
            }

            public long mult(long... x) {
                long r = 1;
                for (long i : x)
                    r = mult(r, i);
                return r;
            }

            public long mult(long a, long b) {
                return (a * b) % modulus();
            }

            public long div(long a, long b) {
                return mult(a, inv(b));
            }

            public long inv(long value) {
                long g = modulus(), x = 0, y = 1;
                for (long r = value; r != 0; ) {
                    long q = g / r;
                    g %= r;

                    long temp = g;
                    g = r;
                    r = temp;

                    x -= q * y;

                    temp = x;
                    x = y;
                    y = temp;
                }

                ASSERT(g == 1);
                ASSERT(y == modulus() || y == -modulus());

                return normalize(x);
            }

        }

        public static class Mod998 extends NumberTheory.Modulus<NumberTheory.Mod998> {
            public long modulus() {
                return 998_244_353L;
            }

        }

    }

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

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

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

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

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.function.IntBinaryOperator;
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);
            GChattering solver = new GChattering();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class GChattering {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int[] rs = new int[n];
            for (int i = 0; i < n; i++) {
                rs[i] = in.readInt();
            }

            if (n == 1) {
                out.println(0);
                return;
            }

            int[] leftTo = new int[3 * n];
            int[] rightTo = new int[3 * n];
            for (int i = 0; i < 3 * n; i++) {
                leftTo[i] = Math.max(0, i - rs[i % n]);
                rightTo[i] = Math.min(3 * n - 1, i + rs[i % n]);
            }

            int[] indexes = new int[3 * n];
            for (int i = 0; i < 3 * n; i++) {
                indexes[i] = i;
            }

            IntegerSparseTable leftST = new IntegerSparseTable(indexes, indexes.length, (a, b) -> leftTo[a] <= leftTo[b] ? a : b);
            IntegerSparseTable rightST = new IntegerSparseTable(indexes, indexes.length, (a, b) -> rightTo[a] >= rightTo[b] ? a : b);

            int[][] dpL = new int[20][3 * n];
            int[][] dpR = new int[20][3 * n];
            dpL[0] = leftTo;
            dpR[0] = rightTo;

            for (int i = 1; i < 20; i++) {
                for (int j = n; j < n * 2; j++) {
                    int l = dpL[i - 1][j];
                    int r = dpR[i - 1][j];
                    int lIndex = leftST.query(l, r);
                    int rIndex = rightST.query(l, r);
                    l = Math.min(l, dpL[i - 1][lIndex]);
                    l = Math.min(l, dpL[i - 1][rIndex]);
                    r = Math.max(r, dpR[i - 1][lIndex]);
                    r = Math.max(r, dpR[i - 1][rIndex]);
                    dpL[i][j] = l;
                    dpR[i][j] = r;
                }
                for (int j = 0; j < n; j++) {
                    dpL[i][j] = Math.max(0, dpL[i][j + n] - n);
                    dpR[i][j] = dpR[i][j + n] - n;
                }
                for (int j = 2 * n; j < 3 * n; j++) {
                    dpL[i][j] = dpL[i][j - n] + n;
                    dpR[i][j] = Math.min(3 * n - 1, dpR[i][j - n] + n);
                }
            }

            //System.err.println(Arrays.deepToString(dpL));
            // System.err.println(Arrays.deepToString(dpR));

            for (int i = n; i < 2 * n; i++) {
                int mask = 0;
                int ll = i;
                int rr = i;
                for (int j = 20 - 1; j >= 0; j--) {
                    int l = ll;
                    int r = rr;
                    int lIndex = leftST.query(l, r);
                    int rIndex = rightST.query(l, r);
                    l = Math.min(l, dpL[j][lIndex]);
                    l = Math.min(l, dpL[j][rIndex]);
                    r = Math.max(r, dpR[j][lIndex]);
                    r = Math.max(r, dpR[j][rIndex]);

                    if (r - l + 1 < n) {
                        mask = Bits.setBit(mask, j, true);
                        ll = l;
                        rr = r;
                    }
                }

                out.println(mask + 1);
            }
        }

    }

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

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

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

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

        public int readInt() {
            int sign = 1;

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

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

            return val;
        }

    }

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

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

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

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

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

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

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

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

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

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

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

    }

    static class Bits {
        private Bits() {
        }

        public static int setBit(int x, int i, boolean v) {
            if (v) {
                x |= 1 << i;
            } else {
                x &= ~(1 << i);
            }
            return x;
        }

    }

    static class IntegerSparseTable {
        private int[][] st;
        private IntBinaryOperator merger;

        public IntegerSparseTable(int[] data, int length, IntBinaryOperator merger) {
            int m = CachedLog2.floorLog(length);
            st = new int[m + 1][length];
            this.merger = merger;
            for (int i = 0; i < length; i++) {
                st[0][i] = data[i];
            }
            for (int i = 0; i < m; i++) {
                int interval = 1 << i;
                for (int j = 0; j < length; j++) {
                    if (j + interval < length) {
                        st[i + 1][j] = merge(st[i][j], st[i][j + interval]);
                    } else {
                        st[i + 1][j] = st[i][j];
                    }
                }
            }
        }

        private int merge(int a, int b) {
            return merger.applyAsInt(a, b);
        }

        public int query(int left, int right) {
            int queryLen = right - left + 1;
            int bit = CachedLog2.floorLog(queryLen);
            // x + 2^bit == right + 1
            // So x should be right + 1 - 2^bit - left=queryLen - 2^bit
            return merge(st[bit][left], st[bit][right + 1 - (1 << bit)]);
        }

        public String toString() {
            return Arrays.toString(st[0]);
        }

    }

    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 floorLog(int x) {
            return x < LIMIT ? CACHE[x] : (BITS + CACHE[x >>> BITS]);
        }

    }
}


//package codeforces;

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

public class D {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

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

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

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

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

    int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    @SuppressWarnings("unchecked")
    void solve() throws IOException {
        final int n = nextInt();
        final char[][] a = new char[n][];
        for (int i = 0; i < n; i++) {
            a[i] = next().toCharArray();
        }
        class Utils {
            int play(int i, int j) {
                int score = 0;
                if(a[i][j] == 'a') {
                    score++;
                }
                if(a[i][j] == 'b') {
                    score--;
                }
                if(i == n - 1 && j == n - 1) {
                    return score;
                }
                if(i == n - 1) {
                    return score + play(i, j + 1);
                }
                if(j == n - 1) {
                    return score + play(i + 1, j);
                }
                if((i + j) % 2 == 1) {
                    return score + Math.max(play(i + 1, j), play(i, j + 1));
                } else {
                    return score + Math.min(play(i + 1, j), play(i, j + 1));
                }
            }
        }
        class CachedUtils extends Utils {
            int[][] cache = new int[n][n];
            boolean[][] hit = new boolean[n][n];

            @Override
            int play(int i, int j) {
                if(!hit[i][j]) {
                    hit[i][j] = true;
                    cache[i][j] = super.play(i, j);
                }
                return cache[i][j];
            }
        }
        int score = new CachedUtils().play(0, 0);
        writer.println(score == 0 ? "DRAW" : (score > 0 ? "FIRST" : "SECOND"));
        writer.close();
    }

    public static void main(String[] args) throws IOException {
//        new D().test();
        new D().solve();
    }
}


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

public class Task {
	FastScanner in;
	PrintWriter out;

	public void solve() throws IOException {
		int n = in.nextInt();
		char[][] a = new char[n][n];
		for (int i = 0; i < n; i++) {
			a[i] = in.next().toCharArray();
		}
		long[][] dp = new long[n][n];
		for (int i = n - 1; i >= 0; i--) {
			for (int j = n - 1; j >= 0; j--) {
				boolean aPlayer = (i + j) % 2 != 0;
				if (i == n - 1 && j == n - 1) {
					dp[i][j] = 0;
					continue;
				}
				long min = Integer.MAX_VALUE;
				if (j < n - 1) {
					long cur = dp[i][j + 1];
					long score = 0;
					if (a[i][j + 1] == 'a') score++;
					if (a[i][j + 1] == 'b') score--;
					if (!aPlayer) score = -score;
					cur -= score;
					min = Math.min(min, cur);
				}
				if (i < n - 1) {
					long cur = dp[i + 1][j];
					long score = 0;
					if (a[i + 1][j] == 'a') score++;
					if (a[i + 1][j] == 'b') score--;
					if (!aPlayer) score = -score;
					cur -= score;
					min = Math.min(min, cur);
				}
				dp[i][j] = -min;
			}
		}
		dp[0][0] = -dp[0][0];
		if (a[0][0] == 'a') dp[0][0]++;
		if (a[0][0] == 'b') dp[0][0]--;
		if (dp[0][0] > 0) out.println("FIRST");
		else if (dp[0][0] < 0) out.println("SECOND");
		else out.println("DRAW");
	}

	public void run() {
		try {
			in = new FastScanner();
			out = new PrintWriter(System.out);

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

	public static void main(String[] arg) {
		new Task().run();
	}
}


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

public class GameOnStrings {
	public static void main(String[] args) throws IOException {
		BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(rd.readLine());
		board = new char[n][n];
		for(int i=0; i<n; i++){
			String line = rd.readLine();
			for(int j=0; j<n; j++)
				board[i][j] = line.charAt(j);
		}
		for(int i=0; i<=20; i++)
			for(int j=0; j<=20; j++)
				for(int k=0; k<=40; k++)
					Arrays.fill(dp[i][j][k], -1);
		int firstWins = count(0, 0, (board[0][0]=='a'? 1: 0), (board[0][0]=='b'? 1: 0));
		if(firstWins>0){
			System.out.println("First");
			return;
		}
		for(int i=0; i<=20; i++)
			for(int j=0; j<=20; j++)
				for(int k=0; k<=40; k++)
					Arrays.fill(dp[i][j][k], -1);
		int secondWins = count2(0, 0, (board[0][0]=='a'? 1: 0), (board[0][0]=='b'? 1: 0));
		if(secondWins>0){
			System.out.println("Second");
		}
		else
			System.out.println("Draw");
	}

	static int count2(int x, int y, int A, int B){
		if(dp[x][y][A][B]!=-1){
	//		System.out.println(x+" " +y+" "+A+" "+B+" "+dp[x][y][A][B]);
			return dp[x][y][A][B];
		}
		int whoseTurn = (x+y+1)%2;
		if(x==n-1 && y==n-1){
			int ans = (A<B? 1: 0);
	//		System.out.println(x+" " +y+" "+A+" "+B+" "+ans);
			return dp[x][y][A][B] = ans;
		}
		int choice1 = (x+1<n? count2(x+1, y, (board[x+1][y]=='a'? A+1: A), (board[x+1][y]=='b'? B+1: B)) : -1);
		int choice2 = (y+1<n? count2(x, y+1, (board[x][y+1]=='a'? A+1: A), (board[x][y+1]=='b'? B+1: B)) : -1);
		if(whoseTurn==0){
			if(x==0 && y==1 && A==1 && B==1){
	//			System.out.println("ty "+choice1+" "+choice2);
			}
			if(choice1==0 || choice2==0){
	//			System.out.println(x+" " +y+" "+A+" "+B+" "+0);
				return dp[x][y][A][B] = 0;
			}
	//		System.out.println(x+" " +y+" "+A+" "+B+" "+1);
			return dp[x][y][A][B] = 1;
		}
		if(choice1==1 || choice2==1){
	//		System.out.println(x+" " +y+" "+A+" "+B+" "+1);
			return dp[x][y][A][B] = 1;
		}
	//	System.out.println(x+" " +y+" "+A+" "+B+" "+0);
		return dp[x][y][A][B] = 0;
	}

	static int count(int x, int y, int A, int B){
		if(dp[x][y][A][B]!=-1)
			return dp[x][y][A][B];
		int whoseTurn = (x+y+1)%2;
		if(x==n-1 && y==n-1){
			int ans = (A>B? 1: 0);
			return dp[x][y][A][B] = ans;
		}
		int choice1 = (x+1<n ? count(x+1, y, (board[x+1][y]=='a'? A+1: A), (board[x+1][y]=='b'? B+1: B)) : -1);
		int choice2 = (y+1<n ? count(x, y+1, (board[x][y+1]=='a'? A+1: A), (board[x][y+1]=='b'? B+1: B)) : -1);
		if(whoseTurn==0){
			if(choice1==1 || choice2==1){
				return dp[x][y][A][B] = 1;
			}
			return dp[x][y][A][B] = 0;
		}
		if(choice1==0 || choice2==0) return dp[x][y][A][B] = 0;
		return dp[x][y][A][B] = 1;
	}

	static int[][][][] dp = new int[21][21][41][41];

	static int n;

	static char[][] board;

}


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

public class StringPlay {
    public static final int UNREACHABLE = 1000;

    FastScanner in;
    PrintWriter out;

    public void solve() throws IOException {
        int n = in.nextInt();
        char[][] t = new char[n][n];
        for (int i = 0; i < n; i++) {
            t[i] = in.next().toCharArray();
        }

        int[] curr = new int[1 << n];
        Arrays.fill(curr, UNREACHABLE);
        curr[1 << (n - 1)] = 0;

        int[] next = new int[1 << n];
        Arrays.fill(next, UNREACHABLE);
        int[] nextMask = new int['z' - 'a' + 1];

        for (int layer = 2 * n - 2; layer > 0; layer--) {
            boolean first = layer % 2 == 0;

            for (int state = 0; state < next.length; state++) {
                Arrays.fill(nextMask, 0);

                char sel = 0;
                for (int row = 0; row < n; row++) {
                    int bit = 1 << row;
                    if ((state & bit) == 0) {
                        continue;
                    }

                    int col = layer - row - 1;
                    if (col < 0 || col > n - 1) {
                        sel = 0;
                        break;
                    }

                    if (sel == 0) {
                        sel = t[row][col];
                    }
                    if (sel != t[row][col]) {
                        sel = 0;
                        break;
                    }

                    if (col < n - 1) {
                        int ch = t[row][col + 1] - 'a';
                        nextMask[ch] |= (1 << (row));
                    }
                    if (row < n - 1) {
                        int ch = t[row + 1][col] - 'a';
                        nextMask[ch] |= (1 << (row + 1));
                    }
                }

                if (sel == 0) {
                    continue;
                }

                int nonrelaxed = UNREACHABLE;
                for (int i = 0; i < nextMask.length; i++) {
                    int mask = nextMask[i];
                    if (mask == 0) {
                        continue;
                    }

                    int add = getValue((char) ('a' + i));
                    int from = curr[mask];
                    if (from == UNREACHABLE) {
                        continue;
                    }

                    if (nonrelaxed == UNREACHABLE) {
                        nonrelaxed = from + add;
                    } else if (first) {
                        nonrelaxed = Math.max(nonrelaxed, from + add);
                    } else {
                        nonrelaxed = Math.min(nonrelaxed, from + add);
                    }
                }
                next[state] = nonrelaxed;
            }

            int[] tmp = next;
            next = curr;
            curr = tmp;
        }

        int res = curr[1] + getValue(t[0][0]);
        if (res == 0) {
            out.println("DRAW");
        } else {
            out.println(res > 0 ? "FIRST" : "SECOND");
        }
    }

    private int getValue(char c) {
        return c != 'a' ? c == 'b' ? -1 : 0 : 1;
    }

    public void run() {
        try {
            in = new FastScanner(System.in);
            out = new PrintWriter(System.out);

            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

    public static void main(String[] arg) {
        new StringPlay().run();
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
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
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int p2 = 0;
            while ((1 << p2) - 1 <= n) ++p2;
            --p2;
            boolean[] parity = new boolean[(1 << p2) - 1];
            fillParity(parity, 0, parity.length - 1, false);
            int must = (1 << p2) - 1;
            for (int i = 0; i + 1 < parity.length; ++i) {
                if (parity[i] == parity[i + 1])
                    ++must;
            }
            if (n == must) {
                out.println(1);
            } else if (n == must + 1) {
                out.println(2);
            } else if (n == must + 2) {
                out.println(1);
            } else {
                out.println(0);
            }
        }

        private void fillParity(boolean[] parity, int left, int right, boolean val) {
            int mid = (left + right) / 2;
            parity[mid] = val;
            if (left < right) {
                fillParity(parity, left, mid - 1, !val);
                fillParity(parity, mid + 1, right, val);
            }
        }

    }

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

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

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

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

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.io.FileReader;
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);
        ESbalansirovannieDerevyaPoiska solver = new ESbalansirovannieDerevyaPoiska();
        solver.solve(1, in, out);
        out.close();
    }

    static class ESbalansirovannieDerevyaPoiska {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            Map<Integer, Integer> ans = new HashMap<>();

            int cur = 1;
            while (cur <= 1e6) {
                System.err.println(cur + " " + (cur + 1));
                ans.put(cur, 1);
                ans.put(cur + 1, 1);
                cur++;
                if (cur % 2 == 0) {
                    cur *= 2;
                } else {
                    cur = cur * 2 - 1;
                }
            }
            out.println(ans.get(n));
        }

    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

        public FastScanner(String fileName) {
            try {
                br = new BufferedReader(new FileReader(fileName));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

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

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

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
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
 */
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);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            if (n == 2) {
                out.println(1);
                return;
            }

            int k = 0;
            while ((1 << k) - 1 <= n) {
                ++k;
            }
            --k;

            int need = (1 << k) - 1;
            for (int i = 0; i < 1 << (k - 1); i++) {
                if (i % 8 == 0 || i % 8 == 2 || i % 8 == 6) {
                    ++need;
                }
            }

            out.println(n == need || n == need + 1 ? 1 : 0);
        }

    }

    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.util.StringTokenizer;

public class e {
	static final long MOD = 998244353;
	public static void main(String[] args) {
		FS scan = new FS(System.in);

		int N = scan.nextInt();
		long[][] sol = new long[2][N+1];
		sol[0][1] = 0;
		sol[1][1] = 1;
		sol[0][2] = 1;
		sol[1][2] = 0;

		for(int i=3;i<=N;i++) {

			int root = (i+1) / 2;
			int left = root - 1;
			int right = i-root;
			int parity = root%2!=right%2 ? 1 : 0;
			if(root%2 == (parity^1) && right==1)sol[root%2][i] = 0;
			else
				sol[root%2][i] = (sol[(root%2) ^ 1][left] * sol[parity^(root%2)][right]);

			if(i%2 == 1)continue;

			root = root+1;
			left = root-1;
			right = i-root;
			parity = root%2!=right%2 ? 1 : 0;
			if(root%2 == (parity^1) && right==1)sol[root%2][i] = 0;
			else
				sol[root%2][i] = (sol[(root%2) ^ 1][left] * sol[parity^(root%2)][right]);
		}

		System.out.println((sol[0][N]+sol[1][N])%MOD);
	}

	private static class FS {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStream;

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

    static class TaskG {
        public long[] prime;
        public long[] power;
        public int mod = 1000000007;
        public long[] dp;
        public int nzeros;
        public ArrayList<ArrayList<Long>> allowed;
        public HashMap<Pair<Integer, Long>, Long> hm;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            char[] c = in.next().toCharArray();
            nzeros = 0;
            for (int i = 0; i < c.length; i++) {
                if (c[i] == '0') {
                    nzeros++;
                }
            }
            int n = in.nextInt();
            prime = new long[n];
            power = new long[n];
            for (int i = 0; i < n; i++) {
                prime[i] = in.nextInt();
                power[i] = in.nextInt();
            }
            dp = new long[nzeros + 1];
            dp[0] = 1;

            allowed = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                if (prime[i] <= c.length) {
                    ArrayList<Long> dd = new ArrayList<>();
                    for (int j = 0; j < prime[i]; j++) {
                        boolean bad = false;
                        long d = 0;
                        for (int k = j; k < c.length; k += prime[i]) {
                            d |= 1L << k;
                            if (c[k] == '1') {
                                bad = true;
                            }
                        }
                        if (!bad) {
                            dd.add(d);
                        }
                    }
                    allowed.add(dd);
                } else {
                    long[] next = new long[dp.length];
                    for (int j = 0; j < dp.length; j++) {
                        // skip all
                        next[j] = (next[j] + (prime[i] - c.length) * dp[j]) % mod;
                        // hit exist
                        next[j] = (next[j] + j * dp[j]) % mod;
                        // hit new
                        if (j + 1 < dp.length) {
                            next[j + 1] = (next[j + 1] + (nzeros - j) * dp[j]) % mod;
                        }
                    }
                    dp = next;
                }
            }
            hm = new HashMap<>();
            long nways = dfs(0, 0);
            for (int i = 0; i < n; i++)
                nways = nways * Utils.mod_exp(prime[i], power[i] - 1, mod) % mod;
            out.println(nways);
        }

        public long dfs(int index, long mask) {
            if (index == allowed.size()) {
                return dp[nzeros - Long.bitCount(mask)];
            }
            Pair<Integer, Long> ps = new Pair<>(index, mask);
            Long ret = hm.get(ps);
            if (ret != null) return ret;
            long ans = 0;
            for (long next : allowed.get(index)) {
                ans = (ans + dfs(index + 1, mask | next)) % mod;
            }
            hm.put(ps, ans);
            return ans;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

    }

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

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

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

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

    }

    static class Utils {
        public static long mod_exp(long b, long e, long mod) {
            long res = 1;
            while (e > 0) {
                if ((e & 1) == 1)
                    res = (res * b) % mod;
                b = (b * b) % mod;
                e >>= 1;
            }
            return res;
        }

    }

    static class Pair<U extends Comparable<U>, V extends Comparable<V>> implements Comparable<Pair<U, V>> {
        public final U u;
        public final V v;

        public Pair(U u, V v) {
            this.u = u;
            this.v = v;
        }

        public int hashCode() {
            return (u == null ? 0 : u.hashCode() * 31) + (v == null ? 0 : v.hashCode());
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;
            Pair<U, V> p = (Pair<U, V>) o;
            return (u == null ? p.u == null : u.equals(p.u)) && (v == null ? p.v == null : v.equals(p.v));
        }

        public int compareTo(Pair<U, V> b) {
            int cmpU = u.compareTo(b.u);
            return cmpU != 0 ? cmpU : v.compareTo(b.v);
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Map;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStream;

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

    static class TaskG {
        public long[] prime;
        public long[] power;
        public int mod = 1000000007;
        public long[] dp;
        public int nzeros;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            char[] c = in.next().toCharArray();
            nzeros = 0;
            for (int i = 0; i < c.length; i++) {
                if (c[i] == '0') {
                    nzeros++;
                }
            }
            int n = in.nextInt();
            long mult = 1;
            prime = new long[n];
            power = new long[n];
            for (int i = 0; i < n; i++) {
                prime[i] = in.nextInt();
                power[i] = in.nextInt();
                mult = mult * Utils.mod_exp(prime[i], power[i] - 1, mod) % mod;
            }
            Arrays.sort(prime);
            int k = 0;
            while (k < n && prime[k] <= c.length) k++;
            dp = new long[nzeros + 1];
            dp[0] = 1;
            for (int i = k; i < n; i++) {
                long[] next = new long[dp.length];
                for (int j = 0; j < dp.length; j++) {
                    // skip all
                    next[j] = (next[j] + (prime[i] - c.length) * dp[j]) % mod;
                    // hit exist
                    next[j] = (next[j] + (nzeros - j) * dp[j]) % mod;
                    // hit new
                    if (j > 0) {
                        next[j] = (next[j] + j * dp[j - 1]) % mod;
                    }
                }
                dp = next;
            }
            HashMap<Long, Integer> dp2 = new HashMap<>();
            dp2.put(0L, 1);
            for (int i = 0; i < k; i++) {
                HashMap<Long, Integer> next = new HashMap<>();
                for (int j = 0; j < prime[i]; j++) {
                    boolean bad = false;
                    long d = 0;
                    for (int w = j; w < c.length; w += prime[i]) {
                        d |= 1L << w;
                        if (c[w] == '1') {
                            bad = true;
                        }
                    }
                    if (!bad) {
                        dp2.forEach((x,v) -> {
                            long nk = x | d;
                            next.put(nk, (v+next.getOrDefault(nk, 0)) % mod);
                        });
                    }
                }
                dp2 = next;
            }
            long nways = 0;
            dp2.forEach((x,v) -> nways = (nways + dp[nzeros - Long.bitCount(x)] * v) % mod);
            nways = nways * mult % mod;
            out.println(nways);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

    }

    static class Utils {
        public static long mod_exp(long b, long e, long mod) {
            long res = 1;
            while (e > 0) {
                if ((e & 1) == 1)
                    res = (res * b) % mod;
                b = (b * b) % mod;
                e >>= 1;
            }
            return res;
        }

    }

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

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

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

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

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStream;

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

    static class TaskG {
        public long[] prime;
        public long[] power;
        public int mod = 1000000007;
        public long[] dp;
        public int nzeros;
        public ArrayList<ArrayList<Long>> allowed;
        public HashMap<Pair<Integer, Long>, Integer> hm;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            char[] c = in.next().toCharArray();
            nzeros = 0;
            for (int i = 0; i < c.length; i++) {
                if (c[i] == '0') {
                    nzeros++;
                }
            }
            int n = in.nextInt();
            prime = new long[n];
            power = new long[n];
            for (int i = 0; i < n; i++) {
                prime[i] = in.nextInt();
                power[i] = in.nextInt();
            }
            dp = new long[nzeros + 1];
            dp[0] = 1;
            allowed = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                if (prime[i] <= c.length) {
                    ArrayList<Long> dd = new ArrayList<>();
                    for (int j = 0; j < prime[i]; j++) {
                        boolean bad = false;
                        long d = 0;
                        for (int k = j; k < c.length; k += prime[i]) {
                            d |= 1L << k;
                            if (c[k] == '1') {
                                bad = true;
                            }
                        }
                        if (!bad) {
                            dd.add(d);
                        }
                    }
                    allowed.add(dd);
                } else {
                    long[] next = new long[dp.length];
                    for (int j = 0; j < dp.length; j++) {
                        // skip all
                        next[j] = (next[j] + (prime[i] - c.length) * dp[j]) % mod;
                        // hit exist
                        next[j] = (next[j] + (nzeros - j) * dp[j]) % mod;
                        // hit new
                        if (j > 0) {
                            next[j] = (next[j] + j * dp[j - 1]) % mod;
                        }
                    }
                    dp = next;
                }
            }
            hm = new HashMap<>();
            long nways = dfs(0, 0);
            for (int i = 0; i < n; i++)
                nways = nways * Utils.mod_exp(prime[i], power[i] - 1, mod) % mod;
            out.println(nways);
        }

        public int dfs(int index, long mask) {
            if (index == allowed.size()) {
                return (int)dp[nzeros - Long.bitCount(mask)];
            }
            Pair<Integer, Long> ps = new Pair<>(index, mask);
            Long ret = hm.get(ps);
            if (ret != null) return ret;
            int ans = 0;
            for (long next : allowed.get(index)) {
                ans = (ans + dfs(index + 1, mask | next)) % mod;
            }
            hm.put(ps, ans);
            return ans;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

    }

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

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

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

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

    }

    static class Utils {
        public static long mod_exp(long b, long e, long mod) {
            long res = 1;
            while (e > 0) {
                if ((e & 1) == 1)
                    res = (res * b) % mod;
                b = (b * b) % mod;
                e >>= 1;
            }
            return res;
        }

    }

    static class Pair<U extends Comparable<U>, V extends Comparable<V>> implements Comparable<Pair<U, V>> {
        public final U u;
        public final V v;

        public Pair(U u, V v) {
            this.u = u;
            this.v = v;
        }

        public int hashCode() {
            return (u == null ? 0 : u.hashCode() * 31) + (v == null ? 0 : v.hashCode());
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;
            Pair<U, V> p = (Pair<U, V>) o;
            return (u == null ? p.u == null : u.equals(p.u)) && (v == null ? p.v == null : v.equals(p.v));
        }

        public int compareTo(Pair<U, V> b) {
            int cmpU = u.compareTo(b.u);
            return cmpU != 0 ? cmpU : v.compareTo(b.v);
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Map;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStream;

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

    static class TaskG {
        public long[] prime;
        public long[] power;
        public int mod = 1000000007;
        public long[] dp;
        public int nzeros;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            char[] c = in.next().toCharArray();
            nzeros = 0;
            for (int i = 0; i < c.length; i++) {
                if (c[i] == '0') {
                    nzeros++;
                }
            }
            int n = in.nextInt();
            long mult = 1;
            prime = new long[n];
            power = new long[n];
            for (int i = 0; i < n; i++) {
                prime[i] = in.nextInt();
                power[i] = in.nextInt();
                mult = mult * Utils.mod_exp(prime[i], power[i] - 1, mod) % mod;
            }
            Arrays.sort(prime);
            int k = 0;
            while (k < n && prime[k] <= c.length) k++;
            dp = new long[nzeros + 1];
            dp[0] = 1;
            for (int i = k; i < n; i++) {
                long[] next = new long[dp.length];
                for (int j = 0; j < dp.length; j++) {
                    // skip all
                    next[j] = (next[j] + (prime[i] - c.length) * dp[j]) % mod;
                    // hit exist
                    next[j] = (next[j] + (nzeros - j) * dp[j]) % mod;
                    // hit new
                    if (j > 0) {
                        next[j] = (next[j] + j * dp[j - 1]) % mod;
                    }
                }
                dp = next;
            }
            HashMap<Long, Integer> dp2 = new HashMap<>();
            dp2.put(0L, 1);
            for (int i = 0; i < k; i++) {
                HashMap<Long, Integer> next = new HashMap<>();
                for (int j = 0; j < prime[i]; j++) {
                    boolean bad = false;
                    long d = 0;
                    for (int w = j; w < c.length; w += prime[i]) {
                        d |= 1L << w;
                        if (c[w] == '1') {
                            bad = true;
                        }
                    }
                    if (!bad) {
                        dp2.forEach((x,v) -> {
                            long nk = x | d;
                            next.put(nk, (v+next.getOrDefault(nk, 0)) % mod);
                        });
                    }
                }
                dp2 = next;
            }
            long nways = dp2.entrySet().stream().mapToLong((x) -> dp[nzeros - Long.bitCount(x.getKey())] * x.getValue() % mod).sum() % mod;
            nways = nways * mult % mod;
            out.println(nways);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

    }

    static class Utils {
        public static long mod_exp(long b, long e, long mod) {
            long res = 1;
            while (e > 0) {
                if ((e & 1) == 1)
                    res = (res * b) % mod;
                b = (b * b) % mod;
                e >>= 1;
            }
            return res;
        }

    }

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

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

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

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

    }
}


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

public class CF {
    FastScanner in;
    PrintWriter out;

    long mod = (long) 1e9 + 7;

    void solve() {
//        for (int i = 1; i <= 10; i++) {
//            for (int j = 1; j <= 10; j++) {
//                System.err.print(sol2(i, j) - sol3(i, j) + " ");
//            }
//            System.err.println();
//        }
         out.println(sol2(in.nextInt(), in.nextInt()));
    }

    long sol2(int n, int m) {
        long res = 0;
        long[][] dp01 = new long[m + 1][n + 1];
        long[][] dp01Sum = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp01[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                dp01Sum[w][h] = (dp01Sum[w - 1][h] + dp01[w][h - 1]) % mod;
                dp01[w][h] = (dp01[w - 1][h] + dp01Sum[w][h]) % mod;
            }
        long[][] dp1 = new long[m + 1][n + 1];
        long[][] dp1Sum = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp1[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                dp1Sum[w][h] = (dp1Sum[w - 1][h] + dp01[w - 1][h - 1]) % mod;
                dp1[w][h] = (dp1[w - 1][h] + dp1Sum[w][h] + dp01[w - 1][h - 1]) % mod;
//                 for (int w1 = 2; w1 < w; w1++) {
//                 dp1[w][h] = (dp1[w][h] + (dp01[w1][h - 1] * (w - w1 + 1))
//                 % mod)
//                 % mod;
//                 }
            }
        long[][] dpSum01 = new long[m + 1][n + 1];
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++)
                dpSum01[w][h] = (dpSum01[w][h - 1] + dp01[w][h]) % mod;
        long[][] dpSum1 = new long[m + 1][n + 1];
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++)
                dpSum1[w][h] = (dpSum1[w][h - 1] + dp1[w][h]) % mod;
        for (int h1 = 1; h1 <= n; h1++)
            for (int w1 = 1; w1 <= m; w1++) {
                long curRes = (dpSum01[w1][h1] * dpSum1[w1][n - h1 + 1]) % mod;
                curRes = (curRes * (m - w1 + 1)) % mod;
                res = (res + curRes) % mod;
            }
        return res;
    }

    long sol3(int n, int m) {
        long res = 0;
        long[][] dp01 = new long[m + 1][n + 1];
        long[][] dp01Sum = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp01[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                dp01Sum[w][h] = (dp01Sum[w - 1][h] + dp01[w][h - 1]) % mod;
                dp01[w][h] = (dp01[w - 1][h] + dp01Sum[w][h]) % mod;
            }
        long[][] dp1 = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp1[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                for (int w1 = 2; w1 < w; w1++) {
                    dp1[w][h] = (dp1[w][h] + (dp01[w1][h - 1] * (w - w1 + 1))
                            % mod)
                            % mod;
                }
            }
        long[][] dp3 = new long[m + 1][n + 1];
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++) {
                for (int h1 = 1; h1 <= h; h1++) {
                    dp3[w][h] = (dp3[w][h] + (dp01[w][h1] * dp1[w][h - h1 + 1])
                            % mod)
                            % mod;

                }
                // dp3[w][h] = dp3[w][h - 1] + dp01[w][h] * dp1[w][h - h + 1];
            }
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++) {
                long curRes = (dp3[w][h] * (n - h + 1)) % mod;
                curRes = (curRes * (m - w + 1)) % mod;
                res = (res + curRes) % mod;
            }
        return res;
    }

    int stupid(int n, int m) {
        int total = n * m;
        int sum = 0;
        boolean[][] field = new boolean[n][m];
        for (int st = 0; st < (1 << total); st++) {
            int it = 0;
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    if (((1 << it++) & st) != 0)
                        field[i][j] = true;
                    else
                        field[i][j] = false;
            int l = -1, r = -1;
            boolean ok = true;
            int[] first = new int[n];
            int[] last = new int[n];
            Arrays.fill(first, -1);
            Arrays.fill(last, -1);
            for (int i = 0; i < n; i++) {
                int cnt = 0;
                for (int j = 0; j < m; j++)
                    if (field[i][j]) {
                        if (cnt == 0)
                            first[i] = j;
                        last[i] = j;
                        cnt++;
                    }
                if (cnt != 2 && cnt != 0)
                    ok = false;
                if (cnt == 2) {
                    r = i;
                    if (l == -1)
                        l = i;
                }
            }
            if (!ok)
                continue;
            if (l == -1 || r == -1)
                continue;
            for (int i = l; i <= r; i++)
                if (first[i] == -1 || last[i] == -1 || first[i] == last[i])
                    ok = false;
            if (!ok)
                continue;
            boolean ok2 = false;
            for (int t = l; t <= r; t++) {
                boolean ok3 = true;
                for (int i = l; i < t; i++) {
                    if (first[i] < first[i + 1] || last[i] > last[i + 1])
                        ok3 = false;
                }
                for (int i = r; i > t; i--)
                    if (first[i] < first[i - 1] || last[i] > last[i - 1])
                        ok3 = false;
                if (ok3)
                    ok2 = true;
            }
            if (ok2)
                sum++;
        }
        return sum;
    }

    void run() {
        try {
            in = new FastScanner(new File("test.in"));
            out = new PrintWriter(new File("test.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

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

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

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

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

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

    public static void main(String[] args) {
        new CF().runIO();
    }
}


import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.io.PrintStream;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;

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

class TaskD {

    public void solve(int testNumber, FastScanner in, FastPrinter out) {
//        test();
        int n = in.nextInt();
        int m = in.nextInt();
        out.println(solve(n, m));
//        if (solve(n, m) != solveStupid(n, m)) {
//            throw new AssertionError();
//        }
    }

    static final int MOD = 1000000007;

    static int solve(int n, int m) {
        int[][] dp = new int[m][n + 1];
        int[][] dp2 = new int[m][n + 1];
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            int s = 0;
            int ss = 0;
            dp[0][i] = 1;
            for (int j = 1; j < m; j++) {
                dp2[j][i] = (ss + s + 1) % MOD;
                s += dp[j][i - 1];
                if (s >= MOD) {
                    s -= MOD;
                }
                ss += s;
                if (ss >= MOD) {
                    ss -= MOD;
                }
                dp[j][i] = (ss + 1) % MOD;
            }
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            int cur = 0;
            for (int j = 1; j < m; j++) {
                cur = (int) ((cur + (long) dp[j][i + 1] * dp2[j][n - i] % MOD * (m - j)) % MOD);
            }
            ans += cur;
            if (ans >= MOD) {
                ans -= MOD;
            }
        }
        return ans;
    }

    }

class FastScanner extends BufferedReader {

    boolean isEOF;

    public FastScanner(InputStream is) {
        super(new InputStreamReader(is));
    }

    public int read() {
        try {
            int ret = super.read();
            if (isEOF && ret < 0) {
                throw new InputMismatchException();
            }
            isEOF = ret == -1;
            return ret;
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    static boolean isWhiteSpace(int c) {
        return c >= 0 && c <= 32;
    }

    public int nextInt() {
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int ret = 0;
        while (c >= 0 && !isWhiteSpace(c)) {
            if (c < '0' || c > '9') {
                throw new NumberFormatException("digit expected " + (char) c
                        + " found");
            }
            ret = ret * 10 + c - '0';
            c = read();
        }
        return ret * sgn;
    }

    }

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}


package main;

import main.Parser;
import main.OutputWriter;

public class TaskD {
    int mod = 1000000007;
    long[][] sum1d = new long[3000][3000];
    long[][] sum2d = new long[3000][3000];

    public void solve(int testNumber, Parser in, OutputWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();

        for (int rows = 0; rows <= n; rows++) {
            for (int i = 2; i <= m; i++) {
                sum1d[rows][i] = (rows==0) ? 1 : sum2d[rows-1][i]+1;
                if (i != 0) sum1d[rows][i] += sum1d[rows][i-1];

                sum2d[rows][i] = sum1d[rows][i];
                if (i != 0) sum2d[rows][i] += sum2d[rows][i-1];
            }
        }

        long tot = 0;
        for (int i = 0; i < n; i++) {
            for (int mid = 2; mid <= m; mid++) {
                // res=(res+(((((pd[w][t][1]-pd[w][t-1][1]+M)%M)*pd[w][n-t+1][1])%M)*(m-w+1))%M)%M;
                long top = (i==0) ? 1 : (sum2d[i-1][mid-1]+sum1d[i-1][mid-1]+1);
                long bot = (n-i-1==0) ? 1 : sum2d[n-i-2][mid]+1;

                bot = (bot * top) % mod;
                bot = (bot * (m-mid+1)) % mod;
                tot = (tot + bot) % mod;
            }
        }

        out.println(tot);
    }
}


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

public class CF {
    FastScanner in;
    PrintWriter out;

    long mod = (long) 1e9 + 7;

    void solve() {
//        for (int i = 1; i <= 10; i++) {
//            for (int j = 1; j <= 10; j++) {
//                System.err.print(sol2(i, j) - sol3(i, j) + " ");
//            }
//            System.err.println();
//        }
         out.println(sol2(in.nextInt(), in.nextInt()));
    }

    long sol2(int n, int m) {
        long res = 0;
        long[][] dp01 = new long[m + 1][n + 1];
        long[][] dp01Sum = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp01[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                dp01Sum[w][h] = (dp01Sum[w - 1][h] + dp01[w][h - 1]) % mod;
                dp01[w][h] = (dp01[w - 1][h] + dp01Sum[w][h]) % mod;
            }
        long[][] dp1 = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp1[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                for (int w1 = 2; w1 < w; w1++) {
                    dp1[w][h] = (dp1[w][h] + (dp01[w1][h - 1] * (w - w1 + 1))
                            % mod)
                            % mod;
                }
            }
        long[][] dpSum01 = new long[m + 1][n + 1];
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++)
                dpSum01[w][h] = (dpSum01[w][h - 1] + dp01[w][h]) % mod;
        long[][] dpSum1 = new long[m + 1][n + 1];
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++)
                dpSum1[w][h] = (dpSum1[w][h - 1] + dp1[w][h]) % mod;
        for (int h1 = 1; h1 <= n; h1++)
            for (int w1 = 1; w1 <= m; w1++) {
                long curRes = (dpSum01[w1][h1] * dpSum1[w1][n - h1 + 1]) % mod;
                curRes = (curRes * (m - w1 + 1)) % mod;
                res = (res + curRes) % mod;
            }
        return res;
    }

    long sol3(int n, int m) {
        long res = 0;
        long[][] dp01 = new long[m + 1][n + 1];
        long[][] dp01Sum = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp01[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                dp01Sum[w][h] = (dp01Sum[w-1][h] + dp01[w][h - 1]) % mod;
                dp01[w][h] = (dp01[w - 1][h] + dp01Sum[w][h]) % mod;
            }
        long[][] dp1 = new long[m + 1][n + 1];
        for (int w = 2; w <= m; w++)
            dp1[w][1] = 1;
        for (int h = 2; h <= n; h++)
            for (int w = 2; w <= m; w++) {
                for (int w1 = 2; w1 < w; w1++) {
                    dp1[w][h] = (dp1[w][h] + (dp01[w1][h - 1] * (w - w1 + 1))
                            % mod)
                            % mod;
                }
            }
        long[][] dp3 = new long[m + 1][n + 1];
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++) {
                for (int h1 = 1; h1 <= h; h1++) {
                    dp3[w][h] = (dp3[w][h] + (dp01[w][h1] * dp1[w][h - h1 + 1])
                            % mod)
                            % mod;

                }
//              dp3[w][h] = dp3[w][h - 1] + dp01[w][h] * dp1[w][h - h + 1];
            }
        for (int h = 1; h <= n; h++)
            for (int w = 1; w <= m; w++) {
                long curRes = (dp3[w][h] * (n - h + 1) ) % mod;
                curRes = (curRes * (m - w +1)) % mod;
                res = (res + curRes) % mod;
            }
        return res;
    }

    int stupid(int n, int m) {
        int total = n * m;
        int sum = 0;
        boolean[][] field = new boolean[n][m];
        for (int st = 0; st < (1 << total); st++) {
            int it = 0;
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    if (((1 << it++) & st) != 0)
                        field[i][j] = true;
                    else
                        field[i][j] = false;
            int l = -1, r = -1;
            boolean ok = true;
            int[] first = new int[n];
            int[] last = new int[n];
            Arrays.fill(first, -1);
            Arrays.fill(last, -1);
            for (int i = 0; i < n; i++) {
                int cnt = 0;
                for (int j = 0; j < m; j++)
                    if (field[i][j]) {
                        if (cnt == 0)
                            first[i] = j;
                        last[i] = j;
                        cnt++;
                    }
                if (cnt != 2 && cnt != 0)
                    ok = false;
                if (cnt == 2) {
                    r = i;
                    if (l == -1)
                        l = i;
                }
            }
            if (!ok)
                continue;
            if (l == -1 || r == -1)
                continue;
            for (int i = l; i <= r; i++)
                if (first[i] == -1 || last[i] == -1 || first[i] == last[i])
                    ok = false;
            if (!ok)
                continue;
            boolean ok2 = false;
            for (int t = l; t <= r; t++) {
                boolean ok3 = true;
                for (int i = l; i < t; i++) {
                    if (first[i] < first[i + 1] || last[i] > last[i + 1])
                        ok3 = false;
                }
                for (int i = r; i > t; i--)
                    if (first[i] < first[i - 1] || last[i] > last[i - 1])
                        ok3 = false;
                if (ok3)
                    ok2 = true;
            }
            if (ok2)
                sum++;
        }
        return sum;
    }

    void run() {
        try {
            in = new FastScanner(new File("test.in"));
            out = new PrintWriter(new File("test.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

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

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

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

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

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

    public static void main(String[] args) {
        new CF().runIO();
    }
}


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

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

class TaskC {
    public void solve(int testNumber, Reader in, PrintWriter out) {
        char[] a = in.nextLine().toCharArray();
        int res = 0;
        for (char q : a) {
            if (q >= 'A' && q <= 'Z') res += (q - 'A' + 1);
            if (q >= 'a' && q <= 'z') res -= (q - 'a' + 1);
        }
        out.println(res);
    }
}

class Reader {
    private BufferedReader in;

    public Reader(InputStream is) {
        in = new BufferedReader(new InputStreamReader(is));
    }

    public String nextLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}


/*
 * Code Author: Sanket Udgirkar.
 * DA-IICT
 */
import java.util.*;
import java.io.*;

import javax.swing.plaf.synth.SynthSpinnerUI;
public class Tester
{
	public static long mod;

	public static void main(String[] args)
	{
		InputReader s=new InputReader(System.in);
        OutputStream outputStream = System.out;
        //PrintWriter out=new PrintWriter(outputStream);

        String str=s.nextLine();
        int ans=0;

        for(int i=0; i<str.length(); i++)
        {
        	if((int)str.charAt(i)>=65 && (int)str.charAt(i)<=90)
        		ans=ans+((int)str.charAt(i)-64);
        	else if((int)str.charAt(i)>=97 && (int)str.charAt(i)<=122)
        		ans=ans-((int)str.charAt(i)-96);
        }

        System.out.println(ans);

        //out.close();
	}

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

	static long exp(long a, long b)
	{
		if(b==0)
			return 1;
		if(b==1)
			return a;
		if(b==2)
			return a*a;

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

	static class Pair implements Comparable<Pair>
	{
		long x,f;
		Pair(long ii, long cc)
		{
			x=ii;
			f=cc;
		}

		public int compareTo(Pair o)
		{
			return Long.compare(this.x, o.x);
		}

	}

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

    	public InputReader(InputStream inputstream)
    	{
    	      reader = new BufferedReader(new InputStreamReader(inputstream));
    	      tokenizer = null;
    	}

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

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

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

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

    	public int[] nextIntArray(int n)
    	{
    		int a[] = new int[n];

    		for (int i = 0; i < n; i++)
    				a[i] = nextInt();

    		return a;
    	}

    	public void printArray(int x[])
    	{
    		for(int i=0; i<x.length; i++)
    			System.out.print(x[i]+" ");

    		System.out.println();
    	}
    }

}


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

public class C {

    void solve() throws IOException {
        String s=nextToken();
        int res=0;
        for(int i=0;i<s.length();i++)
            if(s.charAt(i)>='a'&&s.charAt(i)<='z')
                res-=s.charAt(i)-'a'+1;
        else
            if(s.charAt(i)>='A'&&s.charAt(i)<='Z')
                res+=s.charAt(i)-'A'+1;
        out.println(res);

    }

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

    void run() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
//		reader = new BufferedReader(new FileReader("input.txt"));
        tokenizer = null;
        out = new PrintWriter(new OutputStreamWriter(System.out));
//		out = new PrintWriter(new FileWriter("output.txt"));
        solve();
        reader.close();
        out.flush();

    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

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

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

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

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


import java.util.Scanner;

public class SPENCERISGOD {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		boolean spencerIsGod = true;
		while (spencerIsGod) { //AKA always
			System.out.println("ALL PRAISE TO SPENCER, OUR LORD AND SAVIOR, CREATOR OF THE SACRED THREE LOOP. HE HAS DELIVERED US FROM OUR PROCEDURAL PROGRAMMING, AND SHOWED US THE LIGHT OF OBJECT-ORIENTED. MAY HIS CODE FOREVER BE AS PERFECT AS HE IS, FOREVER AND EVER, A-JAVA.");
		}
	}
}