Seryozha conducts a course dedicated to building a map of heights of Stepanovo recreation center. He laid a rectangle grid of size $$$n \times 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 \times 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 \times b$$$ of matrix of heights ($$$1 \le a \le n$$$, $$$1 \le b \le 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 \times b$$$ with top left corners in $$$(i, j)$$$ over all $$$1 \le i \le n - a + 1$$$ and $$$1 \le j \le m - b + 1$$$.Consider the sequence $$$g_i = (g_{i - 1} \cdot x + y) \bmod z$$$. You are given integers $$$g_0$$$, $$$x$$$, $$$y$$$ and $$$z$$$. By miraculous coincidence, $$$h_{i, j} = g_{(i - 1) \cdot m + j - 1}$$$ ($$$(i - 1) \cdot m + j - 1$$$ is the index).

The first line of the input contains four integers $$$n$$$, $$$m$$$, $$$a$$$ and $$$b$$$ ($$$1 \le n, m \le 3\,000$$$, $$$1 \le a \le n$$$, $$$1 \le b \le 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 \le g_0, x, y < z \le 10^9$$$).

Print a single integer — the answer to the problem.

using System;
using System.Collections.Generic;
using System.Linq;
using CompLib.Util;

public class Program
{
    private int N, M, A, B;
    private int G0, X, Y, Z;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        M = sc.NextInt();
        A = sc.NextInt();
        B = sc.NextInt();

        int[] g = new int[N * M];
        g[0] = sc.NextInt();
        X = sc.NextInt();
        Y = sc.NextInt();
        Z = sc.NextInt();
        for (int i = 1; i < N * M; i++)
        {
            g[i] = (int) (((long) g[i - 1] * X + Y) % Z);
        }

        var mq = new MinQueue[N];
        for (int i = 0; i < N; i++)
        {
            mq[i] = new MinQueue();
        }

        for (int j = 0; j < B - 1; j++)
        {
            for (int i = 0; i < N; i++)
            {
                mq[i].Enqueue(g[i * M + j]);
            }
        }

        long ans = 0;
        for (int j = B - 1; j < M; j++)
        {
            for (int i = 0; i < N; i++)
            {
                mq[i].Enqueue(g[i * M + j]);
            }

            var mq2 = new MinQueue();
            for (int i = 0; i < A - 1; i++)
            {
                mq2.Enqueue(mq[i].GetMin());
            }

            for (int i = A - 1; i < N; i++)
            {
                mq2.Enqueue(mq[i].GetMin());
                ans += mq2.GetMin();
                mq2.Dequeue();
            }

            for (int i = 0; i < N; i++)
            {
                mq[i].Dequeue();
            }
        }

        Console.WriteLine(ans);
    }

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

class MinStack
{
    private Stack<(int val, int min)> S;

    public MinStack()
    {
        S = new Stack<(int val, int min)>();
    }

    public int GetMin()
    {
        if (S.Count == 0) return int.MaxValue;
        return S.Peek().min;
    }

    public void Push(int val)
    {
        S.Push((val, Math.Min(val, GetMin())));
    }

    public int Pop()
    {
        return S.Pop().val;
    }

    public int Count
    {
        get { return S.Count; }
    }
}

class MinQueue
{
    public MinStack L, R;

    public MinQueue()
    {
        L = new MinStack();
        R = new MinStack();
    }

    public void Enqueue(int val)
    {
        R.Push(val);
    }

    public void Dequeue()
    {
        if (L.Count == 0)
        {
            while (R.Count > 0)
            {
                L.Push(R.Pop());
            }
        }

        L.Pop();
    }

    public int GetMin()
    {
        return Math.Min(L.GetMin(), R.GetMin());
    }
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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

using CompLib.Util;
using System;
using System.Collections.Generic;

public class Program
{
    private int N, M, A, B;
    private int G0, X, Y, Z;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        M = sc.NextInt();
        A = sc.NextInt();
        B = sc.NextInt();

        G0 = sc.NextInt();
        X = sc.NextInt();
        Y = sc.NextInt();
        Z = sc.NextInt();

        int[] H = new int[N * M];
        H[0] = G0;
        for (int i = 1; i < N * M; i++)
        {
            H[i] = (int) (((long) H[i - 1] * X + Y) % Z);
        }

        MinimumQueue[] q = new MinimumQueue[N];
        for (int i = 0; i < N; i++)
        {
            q[i] = new MinimumQueue();
            for (int j = 0; j < B - 1; j++)
            {
                q[i].Enqueue(H[i * M + j]);
            }
        }

        long ans = 0;
        for (int j = B - 1; j < M; j++)
        {
            var q2 = new MinimumQueue();
            for (int i = 0; i < N; i++)
            {
                q[i].Enqueue(H[i * M + j]);
                q2.Enqueue(q[i].Min());
                if (i >= A - 1)
                {
                    ans += q2.Min();
                    q2.Dequeue();
                }

                q[i].Dequeue();
            }
        }

        Console.WriteLine(ans);
    }

    public static void Main(string[] args) => new Program().Solve();
}

class MinimumStack
{
    private readonly Stack<(int num, int min)> stack;

    public MinimumStack()
    {
        stack = new Stack<(int num, int min)>();
    }

    public void Push(int num)
    {
        if (Count == 0) stack.Push((num, num));
        else stack.Push((num, Math.Min(num, stack.Peek().min)));
    }

    public int Peek()
    {
        return stack.Peek().num;
    }

    public int Pop()
    {
        return stack.Pop().num;
    }

    public int Min()
    {
        return Count == 0 ? int.MaxValue : stack.Peek().min;
    }

    public int Count => stack.Count;
}

class MinimumQueue
{
    private readonly MinimumStack s1, s2;

    public MinimumQueue()
    {
        s1 = new MinimumStack();
        s2 = new MinimumStack();
    }

    public void Enqueue(int l)
    {
        s2.Push(l);
    }

    private void Exec()
    {
        if (s1.Count == 0)
        {
            while (s2.Count > 0)
            {
                s1.Push(s2.Pop());
            }
        }
    }

    public int Peek()
    {
        Exec();
        return s1.Peek();
    }

    public int Dequeue()
    {
        Exec();
        return s1.Pop();
    }

    public int Min()
    {
        return Math.Min(s1.Min(), s2.Min());
    }

    public int Count => s1.Count + s2.Count;
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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

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

class Solution
{
	class SlideMin
	{
		int i = 0;
		List<int> lst = new List<int>();
		public void Push(int x)
		{
			while (lst.Count > i && lst.Last() > x) lst.RemoveAt(lst.Count-1);
			lst.Add(x);
		}
		public void Pop(int x)
		{
			if (lst[i] == x) i++;
		}
		public int Top()
		{
			return lst[i];
		}
	};

	int n, m, a, b;
	int[,] M;

	void Make(int g, int x, int y, int z)
	{
		M = new int[n, m];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				M[i, j] = g;
				g = (int)(((long)g * x + y) % z);
			}
		}
	}

	void Run()
	{
		var A = Array.ConvertAll(cin.ReadLine().Split(), int.Parse);
		n = A[0]; m = A[1]; a = A[2]; b = A[3];
		A = Array.ConvertAll(cin.ReadLine().Split(), int.Parse);
		Make(A[0], A[1], A[2], A[3]);

		int[,] MinRow = new int[n, m - b + 1];
		for (int i = 0; i < n; i++)
		{
			SlideMin slide = new SlideMin();
			for (int j = 0; j < b; j++)
			{
				slide.Push(M[i, j]);
			}
			for (int j = 0; j < m - b + 1; j++)
			{
				MinRow[i, j] = slide.Top();
				if (j == m - b) break;
				slide.Pop(M[i, j]);
				slide.Push(M[i, j + b]);
			}
		}

		long ans = 0;
		for (int j = 0; j < m - b + 1; j++)
		{
			SlideMin slide = new SlideMin();
			for (int i = 0; i < a; i++)
			{
				slide.Push(MinRow[i, j]);
			}
			for (int i = 0; i < n - a + 1; i++)
			{
				ans += slide.Top();
				if (i == n - a) break;
				slide.Pop(MinRow[i, j]);
				slide.Push(MinRow[i + a, j]);
			}
		}

		cout.Write(ans);
	}

	static TextReader cin;
	static TextWriter cout;

	static void Main()
	{
#if NARUT_LOCAL
		cin = new StreamReader("io/test.in", Encoding.ASCII);
#else
		cin = new StreamReader(Console.OpenStandardInput(), Encoding.ASCII);
#endif
		cout = new StreamWriter(Console.OpenStandardOutput(), Encoding.ASCII) { AutoFlush = false };
		(new Solution()).Run();
		cin.Close();
		cout.Close();
	}
}

/*
csc -debug E.cs && mono --debug E.exe <<< "3 4 2 1
1 2 3 59"
*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;

public struct QueueItem {
    public ulong Val;
    public int Index;
}

public class HelloWorld {
    public static void SolveCodeForces() {
        var n = cin.NextInt();
        var m = cin.NextInt();
        var a = cin.NextInt();
        var b = cin.NextInt();

        var Arr = Helpers.CreateArray(n, _ => new ulong[m]);
        {
            var g0 = cin.NextUlong();
            var x = cin.NextUlong();
            var y = cin.NextUlong();
            var z = cin.NextUlong();
            for (var i = 0; i < n; i++)
                for (var j = 0; j < m; j++) {
                    Arr[i][j] = g0;
                    g0 = (g0 * x + y) % z;
                }
        }

// System.Console.WriteLine("Arr:");
// foreach (var row in Arr)
//     System.Console.WriteLine(row.Join());

        var QVers = new Deque<QueueItem>[m];
        for (var j = 0; j < m; j++) {
            var Q = new Deque<QueueItem>();
            for (var i = 0; i < a; i++) {
                var x = Arr[i][j];
                AppendRight(Q, i, x);
            }
            QVers[j] = Q;
        }

        var ans = 0ul;

        for (var i = a - 1; i < n; i++) {
            var rowAns = 0ul;

            var Q = new Deque<QueueItem>();
            for (var j = 0; j < b; j++) {
                AppendRight(Q, j, QVers[j].Left.Val);
            }

            rowAns += Q.Left.Val;
            for (var j = b; j < m; j++) {
                Shift(Q, j - b);
                AppendRight(Q, j, QVers[j].Left.Val);
                rowAns += Q.Left.Val;
            }

            for (var j = 0; j < m; j++) {
                Shift(QVers[j], i - a + 1);
                if (i + 1 < n)
                    AppendRight(QVers[j], i + 1, Arr[i + 1][j]);
            }

// System.Console.WriteLine(new {i, rowAns});
            ans += rowAns;
        }
// System.Console.WriteLine(new {brute = SolveBrute(Arr, n, m, a, b)});

        System.Console.WriteLine(ans);
    }

    static ulong SolveBrute(ulong[][] Arr, int n, int m, int a, int b) {
        var ans = 0ul;

        for (var i = a-1; i < n; i++)
            for (var j = b-1; j < m; j++) {
                var min = Arr[i][j];
                for (var ii = 0; ii < a; ii++)
                    for (var jj = 0; jj < b; jj++)
                        min = Math.Min(min, Arr[i - ii][j - jj]);
                ans += min;
            }

        return ans;
    }

    static void AppendRight(Deque<QueueItem> Q, int i, ulong x) {
        while (Q.Count > 0 && Q.Right.Val >= x) Q.RemoveRight();
        Q.AppendRight(new QueueItem{ Val = x, Index = i });
    }

    static void Shift(Deque<QueueItem> Q, int i) {
        if (Q.Left.Index == i) Q.RemoveLeft();
    }

    static Scanner cin = new Scanner();
    static StringBuilder cout = new StringBuilder();

    static public void Main () {
        SolveCodeForces();
        // IncreaseStack(SolveCodeForces);
        // System.Console.Write(cout.ToString());
    }

    public static void IncreaseStack(ThreadStart action, int stackSize = 128000000)
    {
        var thread = new Thread(action, stackSize);
        thread.Start();
        thread.Join();
    }
}

public class Deque<T> : IEnumerable<T> {
    private T[] arr;
    private int index;
    private int count;
    private int n;

    public Deque(T[] arr) {
        this.arr = arr;
        n = arr.Length;
        count = arr.Length;
    }

    public Deque(int capacity = 8) {
        n = capacity;
        arr = new T[capacity];
    }

    public int Count => count;

    public T Left => this[0];
    public T Right => this[count - 1];

    public T this[int i] {
        get {
            if (i < 0 || i >= count) throw new InvalidOperationException(string.Format("Index {0} is out of range (count = {1})", i, count));
            return arr[(index + i) % n];
        }
    }

    public void AppendRight(T val) {
        EnsureSize();
        arr[(index + count) % n] = val;
        count++;
    }

    public void AppendLeft(T val) {
        EnsureSize();
        index = (index + n - 1) % n;
        arr[index] = val;
        count++;
    }

    public T RemoveLeft() {
        if (count == 0) throw new InvalidOperationException("Can't remove left because deque is empty");

        var result = arr[index];
        index = (index + 1) % n;
        count--;
        return result;
    }

    public T RemoveRight() {
        if (count == 0) throw new InvalidOperationException("Can't remove right because deque is empty");

        var result = arr[(index + count + n - 1) % n];
        count--;
        return result;
    }

    private void EnsureSize() {
        if (count == arr.Length) {
            var newArr = new T[arr.Length * 2];
            var left = Math.Min(count, arr.Length - index);
            Array.Copy(arr, index, newArr, 0, left);
            if (left < count)
                Array.Copy(arr, 0, newArr, left, count - left);
            arr = newArr;
            index = 0;
            n = newArr.Length;
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        for (var i = 0; i < count; i++) {
            yield return arr[(index + i) % n];
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public static class Helpers {
    public static string Join<T>(this IEnumerable<T> arr) {
        return string.Join(" ", arr);
    }

    public static void Swap<T>(ref T a, ref T b) {
        var tmp = a;
        a = b;
        b = tmp;
    }

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

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

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

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

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

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

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

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

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

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

using System;
using CompLib.Collections.Generic;
using CompLib.Util;

public class Program
{
    private int N, M, A, B;
    private int G0, X, Y, Z;

    private long[] H;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        M = sc.NextInt();
        A = sc.NextInt();
        B = sc.NextInt();
        G0 = sc.NextInt();
        X = sc.NextInt();
        Y = sc.NextInt();
        Z = sc.NextInt();

        /*
         * N*Mグリッド
         * セル(i,j) は高さH[i,j]
         *
         * 画面には a*bの範囲が収まる
         *
         * 表示されてる範囲で最小のHの総和
         *
         *
         * g_i = (g_{i-1}*x+y) % Z
         * H[i,j] = g_{(i-1)*m+j-1}
         */

        var st = new SegmentTree[N];
        for (int i = 0; i < N; i++)
        {
            st[i] = new SegmentTree(M);
            for (int j = 0; j < M; j++)
            {
                if (i == 0 && j == 0) st[i][j] = G0;
                else
                {
                    st[i][j] = (int) ((long) st[i / M][i % M] * X + Y) % Z;
                }
            }
        }

        long ans = 0;
        for (int j = 0; j + B <= M; j++)
        {
            var st2 = new SegmentTree(A);
            for (int i = 0; i < A - 1; i++) st2[i] = st[i].Query(j, j + B);
            for (int i = A - 1; i < N; i++)
            {
                st2[i % A] = st[i].Query(j, j + B);
                ans += st2.Root();
            }
        }

        Console.WriteLine(ans);
    }

    int Conv(int i, int j)
    {
        return i * M + j;
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Collections.Generic
{
    using System;

    public class SegmentTree
    {
        private readonly int N;
        private int[] _array;

        private const int _identity = int.MaxValue;

        public SegmentTree(int size)
        {
            N = 1;
            while (N < size) N *= 2;

            _array = new int[N * 2];
            for (int i = 1; i < N * 2; i++)
            {
                _array[i] = _identity;
            }
        }

        /// <summary>
        /// A[i]をnに更新 O(log N)
        /// </summary>
        /// <param name="i"></param>
        /// <param name="n"></param>
        public void Update(int i, int n)
        {
            i += N;
            _array[i] = n;
            while (i > 1)
            {
                i /= 2;
                _array[i] = System.Math.Min(_array[i * 2], _array[i * 2 + 1]);
            }
        }

        private int Query(int left, int right, int k, int l, int r)
        {
            if (r <= left || right <= l)
            {
                return _identity;
            }

            if (left <= l && r <= right)
            {
                return _array[k];
            }

            return Math.Min(Query(left, right, k * 2, l, (l + r) / 2),
                Query(left, right, k * 2 + 1, (l + r) / 2, r));
        }

        public int Root() => _array[1];

        /// <summary>
        /// A[left] op A[left+1] ... op A[right-1]を求める
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public int Query(int left, int right)
        {
            return Query(left, right, 1, 0, N);
        }

        public int this[int i]
        {
            set { Update(i, value); }
            get { return _array[i + N]; }
        }
    }
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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