Seryozha conducts a course dedicated to building a map of heights of Stepanovo recreation center. He laid a rectangle grid of size n × m cells on a map (rows of grid are numbered from 1 to n from north to south, and columns are numbered from 1 to m from west to east). After that he measured the average height of each cell above Rybinsk sea level and obtained a matrix of heights of size n × m. The cell (i, j) lies on the intersection of the i-th row and the j-th column and has height h_{i, j}. 

Seryozha is going to look at the result of his work in the browser. The screen of Seryozha's laptop can fit a subrectangle of size a × b of matrix of heights (1 ≤ a ≤ n, 1 ≤ b ≤ m). Seryozha tries to decide how the weather can affect the recreation center — for example, if it rains, where all the rainwater will gather. To do so, he is going to find the cell having minimum height among all cells that are shown on the screen of his laptop.

Help Seryozha to calculate the sum of heights of such cells for all possible subrectangles he can see on his screen. In other words, you have to calculate the sum of minimum heights in submatrices of size a × b with top left corners in (i, j) over all 1 ≤ i ≤ n - a + 1 and 1 ≤ j ≤ m - b + 1.

Consider the sequence g_i = (g_{i - 1} ⋅ x + y) mod z. You are given integers g_0, x, y and z. By miraculous coincidence, h_{i, j} = g_{(i - 1) ⋅ m + j - 1} ((i - 1) ⋅ m + j - 1 is the index).

Input

The first line of the input contains four integers n, m, a and b (1 ≤ n, m ≤ 3 000, 1 ≤ a ≤ n, 1 ≤ b ≤ m) — the number of rows and columns in the matrix Seryozha has, and the number of rows and columns that can be shown on the screen of the laptop, respectively.

The second line of the input contains four integers g_0, x, y and z (0 ≤ g_0, x, y < z ≤ 10^9).

Output

Print a single integer — the answer to the problem.

Example

Input


3 4 2 1
1 2 3 59


Output


111

Note

The matrix from the first example: 

<image>
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.Random;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

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

    static class EOpenStreetMap {
        Random rnd = new Random(239);

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            if (false) {
                test();
                return;
            }
            int n = in.readInt();
            int m = in.readInt();
            int a = in.readInt();
            int b = in.readInt();
            int g = in.readInt();
            int x = in.readInt();
            int y = in.readInt();
            int z = in.readInt();
            int[][] field = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    field[i][j] = g;
                    g = (int) ((g * (long) x + y) % z);
                }
            }

            out.printLine(new Solver(field, n, m, a, b).solve());
        }

        int[][] gen(int n, int m, int mod) {
            int[][] a = new int[n][];
            for (int i = 0; i < n; i++) {
                a[i] = genRow(m, mod);
            }
            return a;
        }

        int[] genRow(int n, int mod) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = rnd.nextInt(mod);
            }
            return a;
        }

        void test() {
            for (int t = 0; ; t++) {
                int n = rnd.nextInt(3) + 1;
                int m = rnd.nextInt(3) + 1;
                int a = rnd.nextInt(n) + 1;
                int b = rnd.nextInt(m) + 1;
                int[][] field = gen(n, m, 5);
                try {
                    long naive = naive(clone(field), a, b);
                    long solve = new Solver(clone(field), n, m, a, b).solve();
                    if (naive != solve) {
                        for (int[] row : field) {
                            System.out.println(Arrays.toString(row));
                        }
                        System.out.println(a + " " + b);
                        System.out.println(naive);
                        System.out.println(solve);
                    }
                } catch (Exception e) {
                    System.err.println(e);
                    new Solver(field, n, m, a, b).solve();
                }
            }
        }

        int[][] clone(int[][] a) {
            int[][] b = new int[a.length][];
            for (int i = 0; i < a.length; i++) {
                b[i] = a[i].clone();
            }
            return b;
        }

        long naive(int[][] field, int a, int b) {
            int n = field.length;
            int m = field[0].length;
            long ans = 0;
            for (int i0 = 0; i0 + a <= n; i0++) {
                for (int j0 = 0; j0 + b <= m; j0++) {
                    int min = field[i0][j0];
                    for (int i = 0; i < a; i++) {
                        for (int j = 0; j < b; j++) {
                            min = Math.min(min, field[i0 + i][j0 + j]);
                        }
                    }
                    ans += min;
                }
            }
            return ans;
        }

        class Solver {
            int[][] field;
            int n;
            int m;
            int a;
            int b;
            Queue q;
            int[] dx = {0, 1};
            int[] dy = {1, 0};

            Solver(int[][] field, int n, int m, int a, int b) {
                this.field = field;
                this.n = n;
                this.m = m;
                this.a = a;
                this.b = b;
                q = new Queue(Math.max(a, b) + 1);
            }

            long solve() {
                for (int i = 0; i < n; i++) {
                    compress(i, 0, 0, b);
                }
                for (int i = 0; i < m; i++) {
                    compress(0, i, 1, a);
                }
                long ans = 0;
                for (int i = 0; i < n - a + 1; i++) {
                    for (int j = 0; j < m - b + 1; j++) {
                        ans += field[i][j];
                    }
                }
                return ans;
            }

            void compress(int r0, int c0, int d, int size) {
                int dx = this.dx[d];
                int dy = this.dy[d];
                q.clear();
                int x0 = r0, y0 = c0;
                for (int i = 1; r0 < n && c0 < m; r0 += dx, c0 += dy, i++) {
                    q.push(field[r0][c0]);
                    if (i >= size) {
                        if (i > size) {
                            q.pop();
                        }
                        field[x0][y0] = q.getMin();
                        x0 += dx;
                        y0 += dy;
                    }
                }
            }

            class Queue {
                Stack s1;
                Stack s2;

                Queue(int size) {
                    s1 = new Stack(size);
                    s2 = new Stack(size);
                }

                int getMin() {
                    return Math.min(s1.getMin(), s2.getMin());
                }

                void push(int x) {
                    s2.push(x);
                }

                void pop() {
                    if (isEmpty()) {
                        return;
                    }
                    if (s1.isEmpty()) {
                        while (!s2.isEmpty()) {
                            s1.push(s2.pop());
                        }
                    }
                    s1.pop();
                }

                int size() {
                    return s1.size() + s2.size();
                }

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

                void clear() {
                    s1.clear();
                    s2.clear();
                }

            }

            class Stack {
                int[] values;
                int[] mins;
                int size;

                Stack(int size) {
                    values = new int[size];
                    mins = new int[size];
                }

                int getMin() {
                    return size == 0 ? Integer.MAX_VALUE : mins[size - 1];
                }

                void push(int x) {
                    values[size] = x;
                    mins[size] = Math.min(x, getMin());
                    size++;
                }

                int pop() {
                    return values[--size];
                }

                int size() {
                    return size;
                }

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

                void clear() {
                    size = 0;
                }

            }

        }

    }

    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 printLine(long i) {
            writer.println(i);
        }

    }

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

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

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

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

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

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

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

        }

    }
}

