# require "template" lib C fun strtoll(s : UInt8*, p : UInt8**, b : Int32) : Int64 end class String def to_i64 C.strtoll(self, nil, 10) end end # require "math/Mint" struct Mint @@MOD = 1_000_000_007i64 def self.mod @@MOD end def self.zero Mint.new end @value : Int64 def initialize @value = 0i64 end def initialize(value) @value = value.to_i64 % @@MOD end def initialize(m : Mint) @value = m.value end protected def value=(value : Int64) @value = value end getter value : Int64 def + : self self end def - : self Mint.new(value != 0 ? @@MOD - @value : 0) end def +(m) self + m.to_mint end def +(m : Mint) result = Mint.new result.value = @value + m.value result.value -= @@MOD if result.value >= @@MOD result end def -(m) self - m.to_mint end def -(m : Mint) result = Mint.new result.value = @value - m.value result.value += @@MOD if result.value < 0 result end def *(m) result = Mint.new result.value = @value * Mint.new(m).value % @@MOD result end def /(m) raise DivisionByZeroError.new if m == 0 a, b, u, v = m.to_i64, @@MOD, 1i64, 0i64 while b != 0 t = a // b a -= t * b a, b = b, a u -= t * v u, v = v, u end Mint.new(@value * u) end def //(m) self / m end def **(m : Int) t, res = self, Mint.new(1) while m > 0 res *= t if m.odd? t *= t m >>= 1 end res end def ==(m) @value == m.to_i64 end def !=(m) @value != m.to_i64 end def succ self + 1 end def pred self - 1 end def to_i64 : Int64 @value end delegate to_s, to: @value delegate inspect, to: @value end struct Int def to_mint : Mint Mint.new(self) end end class String def to_mint : Mint Mint.new(self) end end # require "math/Matrix" class Matrix(T) include Indexable(Array(T)) getter height : Int32 getter width : Int32 getter data : Array(Array(T)) def Matrix.identity(size : Int32) result = Matrix(T).new(size, size) (0...size).each do |i| result[i][i] = T.new(1) end result end def initialize(@height, @width, init_value = T.zero) @data = Array(Array(T)).new(height) { Array(T).new(width, init_value) } end def initialize(init_matrix : Array(Array(T))) @height = init_matrix.size @width = init_matrix[0].size raise ArgumentError.new unless init_matrix.all? { |a| a.size == width } @data = init_matrix end def size data.size end def unsafe_fetch(index : Int) data.unsafe_fetch(index) end def +(other : self) IndexError.new unless height == other.height && width == other.width result = Matrix(T).new(height, width) (0...height).each do |i| (0...width).each do |j| result[i][j] = data[i][j] + other[i][j] end end result end def -(other : self) IndexError.new unless height == other.height && width == other.width result = Matrix(T).new(height, width) (0...height).each do |i| (0...width).each do |j| result[i][j] = data[i][j] - other[i][j] end end result end def *(other : self) IndexError.new unless width == other.height result = Matrix(T).new(height, width) (0...height).each do |i| (0...other.width).each do |j| (0...width).each do |k| result[i][j] += data[i][k] * other[k][j] end end end result end def **(k : Int) result = Matrix(T).identity(height) memo = Matrix.new(data) while k > 0 result *= memo if k.odd? memo *= memo k >>= 1 end result end def to_s(io) io << data end end n, w, k = read_line.split.try { |(n, w, k)| {n.to_i, w.to_i, k.to_i64} } a = read_line.split.map(&.to_i) dp = Array.new(2 * w + 1) { Array.new(2, 0.to_mint) } dp[0][0] = 1.to_mint (1..2 * w).each do |i| (0...n).each do |j| i2 = i - a[j] dp[i][0] += dp[i2][0] if 0 <= i2 dp[i][1] += dp[i2][1] if 0 <= i2 dp[i][1] += dp[i2][0] if 0 <= i2 < w < i end end val1, val2 = dp[w][0], dp[2 * w][1] x = Matrix.new([[val1, val2], [1.to_mint, 0.to_mint]]) y = Matrix.new([[val1], [1.to_mint]]) puts (x**k * y)[1][0]