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();
	}
}

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.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();
    }
}

/*
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();
    }
}