Problem:
Score : 800 points

Problem Statement

The beauty of a sequence a of length n is defined as a_1 \oplus \cdots \oplus a_n, where \oplus denotes the bitwise exclusive or (XOR).

You are given a sequence A of length N.
Snuke will insert zero or more partitions in A to divide it into some number of non-empty contiguous subsequences.

There are 2^{N-1} possible ways to insert partitions.
How many of them divide A into sequences whose beauties are all equal? Find this count modulo 10^{9}+7.

Constraints

All values in input are integers.

1 \leq N \leq 5 \times 10^5

0 \leq A_i < 2^{20}

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 \ldots A_{N}

Output

Print the answer.

Sample Input 1

3
1 2 3

Sample Output 1

3

Four ways of dividing A shown below satisfy the condition. The condition is not satisfied only if A is divided into (1),(2),(3).

(1,2,3)

(1),(2,3)

(1,2),(3)

Sample Input 2

3
1 2 2

Sample Output 2

1

Sample Input 3

32
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Sample Output 3

147483634

Find the count modulo 10^{9}+7.

Sample Input 4

24
1 2 5 3 3 6 1 1 8 8 0 3 3 4 6 6 4 0 7 2 5 4 6 2

Sample Output 4

292

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
using static System.Math;
class Z { static void Main() => new K(); }
class K
{
	int F => int.Parse(Str);
	long FL => long.Parse(Str);
	int[] G => Strs.Select(int.Parse).ToArray();
	uint[] GU => Strs.Select(uint.Parse).ToArray();
	decimal[] GD => Strs.Select(decimal.Parse).ToArray();
	long[] GL => Strs.Select(long.Parse).ToArray();
	string Str => ReadLine();
	string[] Strs => Str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
	static T[] ConstantArray<T>(int n, T val) { var a = new T[n]; for (var i = 0; i < n; i++) a[i] = val; return a; }
	static T[] MakeArray<T>(int n, Func<int, T> f) { var a = new T[n]; for (var i = 0; i < n; i++) a[i] = f(i); return a; }
	static int ArgMax<T>(IList<T> a) where T : IComparable<T> { var m = a[0]; var mi = 0; for (var i = 1; i < a.Count; i++) if (m.CompareTo(a[i]) < 0) { m = a[i]; mi = i; } return mi; }
	static int ArgMin<T>(IList<T> a) where T : IComparable<T> { var m = a[0]; var mi = 0; for (var i = 1; i < a.Count; i++) if (m.CompareTo(a[i]) > 0) { m = a[i]; mi = i; } return mi; }
	static ulong One(int k) => 1ul << k;
	static ulong All(int k) => One(k) - 1;
	static bool Has(ulong s, int k) => (s & One(k)) != 0;
	const int MOD = 1000000007;
	public K()
	{
		SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
		Solve();
		Out.Flush();
	}
	void Solve()
	{
		var N = F;
		var A = G;
		var sum = new int[N + 1];
		for (var i = 0; i < N; i++) sum[i + 1] = sum[i] ^ A[i];
		var zero = new int[N + 2];
		for (var i = 0; i <= N; i++) zero[i + 1] = zero[i] + (sum[i] == 0 ? 1 : 0);
		if (sum[N] == 0)
		{
			var valsSet = new SortedSet<int>(sum);
			valsSet.Remove(0);
			var vals = valsSet.ToList();
			var inv = new Dictionary<int, int>();
			var V = vals.Count;
			for (var i = 0; i < V; i++) inv[vals[i]] = i;
			var ap = MakeArray(V, _ => new List<int>());
			for (var i = 1; i < N; i++) if (sum[i] != 0) ap[inv[sum[i]]].Add(i);
			var ans = Pow(2, zero[N + 1] - 2, MOD);
			for (var i = 0; i < V; i++)
			{
				var p = ap[i].Count;
				var zs = new int[p - 1];
				for (var j = 0; j < p - 1; j++) zs[j] = zero[ap[i][j + 1]] - zero[ap[i][j]];
				var dp = new long[p];
				dp[0] = 1;
				var hoge = 1L;
				for (var j = 1; j < p; j++)
				{
					dp[j] = (dp[j - 1] + zs[j - 1] * hoge % MOD) % MOD;
					hoge = (hoge + dp[j]) % MOD;
				}
				ans += dp.Sum() % MOD;
			}
			WriteLine(ans % MOD);
		}
		else
		{
			var ap = new List<int>();
			for (var i = 1; i < N; i++) if (sum[i] != sum[N]) ap.Add(i);
			var p = ap.Count;
			var zs = new int[p - 1];
			for (var j = 0; j < p - 1; j++) zs[j] = zero[ap[j + 1]] - zero[ap[j]];
			var dp = new long[p];
			dp[0] = 1;
			var hoge = 1L;
			for (var j = 1; j < p; j++)
			{
				dp[j] = (dp[j - 1] + zs[j - 1] * hoge % MOD) % MOD;
				hoge = (hoge + dp[j]) % MOD;
			}
			WriteLine(dp[p - 1]);
		}
	}
	public static long Pow(long a, long b, long mod)
	{
		var p = 1L;
		var x = a;
		while (b > 0)
		{
			if ((b & 1) == 1) p = (p * x) % mod;
			b >>= 1;
			x = (x * x) % mod;
		}
		return p;
	}
}