puwaer/puwaer_code_translation huggingface dataset:
AtCoder problem 072

C++ solution:

Crystal solution: record Point, y : Int32, x : Int32 do
  Direction = [Point.new(0, 1), Point.new(0, -1), Point.new(1, 0), Point.new(-1, 0)]

  def +(other : Point)
    Point.new(y + other.y, x + other.x)
  end
end

class Solve
  getter h : Int32, w : Int32

  def initialize
    @h, @w = read_line.split.map(&.to_i)
    @s = Array(String).new(h) { read_line }
    @ans = 0
    @start = Point.new(0, 0)
    @used = Array(Array(Bool)).new(h) { Array(Bool).new(w, false) }
  end

  def run
    Array.each_product((0...h).to_a, (0...w).to_a) do |(y, x)|
      @start = Point.new(y, x)
      @used.map(&.fill(false))
      @used[y][x] = true
      dfs(@start, 0)
    end
    @ans <= 2 ? -1 : @ans
  end

  def dfs(p1, cnt) : Nil
    (0...4).each do |d|
      p2 = p1 + Point::Direction[d]
      next unless (0...h).includes?(p2.y) && (0...w).includes?(p2.x) && @s[p2.y][p2.x] == '.'
      if @start == p2
        @ans = {@ans, cnt + 1}.max
        return
      end
      if !@used[p2.y][p2.x]
        @used[p2.y][p2.x] = true
        dfs(p2, cnt + 1)
        @used[p2.y][p2.x] = false
      end
    end
  end
end

puts Solve.new.run






Ruby solution: require 'thread'

State = Struct.new(:vis, :pos, :src)

h, w = readline.split.map(&:to_i)
w += 1
grid = readlines.join + ('#' * w)

queue = Queue.new
dp = {}
for pos in 0...(h * w)
    if grid[pos] == '.' then
        q = State.new(1 << pos, pos, pos)
        queue.push(q)
        dp[q] = 1
    end
end

ans = 2

until queue.empty?
    q0 = queue.pop

    for δ in [-w, -1, +1, +w]
        pos = q0.pos + δ

        next if grid[pos] != '.'
        q1 = State.new(q0.vis | (1 << pos), pos, q0.src)
        next if dp.include?(q1)
        if q1.vis != q0.vis then
            dp[q1] = dp[q0] + 1
            queue.push(q1)
        elsif q1.pos == q0.src then
            ans = [ans, dp[q0]].max
        end
    end
end

puts (ans == 2) ? -1 : ans
AtCoder problem 072

C++ solution:

Crystal solution: record Point, y : Int32, x : Int32 do
  Direction = [Point.new(0, 1), Point.new(0, -1), Point.new(1, 0), Point.new(-1, 0)]

  def +(other : Point)
    Point.new(y + other.y, x + other.x)
  end
end

class Solve
  getter h : Int32, w : Int32

  def initialize
    @h, @w = read_line.split.map(&.to_i)
    @s = Array(String).new(h) { read_line }
    @ans = 0
    @start = Point.new(0, 0)
    @used = Array(Array(Bool)).new(h) { Array(Bool).new(w, false) }
  end

  def run
    Array.each_product((0...h).to_a, (0...w).to_a) do |(y, x)|
      @start = Point.new(y, x)
      @used.map(&.fill(false))
      @used[y][x] = true
      dfs(@start, 0)
    end
    @ans <= 2 ? -1 : @ans
  end

  def dfs(p1, cnt) : Nil
    (0...4).each do |d|
      p2 = p1 + Point::Direction[d]
      next unless (0...h).includes?(p2.y) && (0...w).includes?(p2.x) && @s[p2.y][p2.x] == '.'
      if @start == p2
        @ans = {@ans, cnt + 1}.max
        return
      end
      if !@used[p2.y][p2.x]
        @used[p2.y][p2.x] = true
        dfs(p2, cnt + 1)
        @used[p2.y][p2.x] = false
      end
    end
  end
end

puts Solve.new.run





Kuin solution: func main()
	var h: int :: cui@inputInt()
	var w: int :: cui@inputInt()
	var c: [][]char :: #[h][]char
	for i(0, h - 1)
		do c[i] :: cui@input()
	end for
	
	var ans: int :: 0
	if(h = 1 | w = 1)
	else
		for y(0, h - 1)
			for x(0, w - 1)
				for d(0, 3)
					if(c[y][x] = '.')
						do ans :: [ans, f(0, y, x, y, x, h, w, c, d)].max()
					end if
				end for
			end for
		end for
	end if
	if(ans = 0)
		do ans :: -1
	end if
	do cui@print("\{ans}\n")
	
	func f(cnt: int, sy: int, sx: int, y: int, x: int, h: int, w: int, c: [][]char, d: int): int
		var res: int :: 0
		var dx: []int :: [1, 0, -1, 0]
		var dy: []int :: [0, 1, 0, -1]
		for dd(-1, 1)
			var nd: int :: (d + dd + 4) % 4
			var nx: int :: x + dx[nd]
			var ny: int :: y + dy[nd]
			if(nx = -1 | nx = w)
				skip dd
			end if
			if(ny = -1 | ny = h)
				skip dd
			end if
			if(ny = sy & nx = sx)
				do res :: [res, cnt + 1].max()
				skip dd
			end if
			if(c[ny][nx] = '#')
				skip dd
			end if
			do c[ny][nx] :: '#'
			do res :: [res, f(cnt + 1, sy, sx, ny, nx, h, w, c, nd)].max()
			do c[ny][nx] :: '.'
		end for
		ret res
	end func
end func
AtCoder problem 072

C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;



int H, W;

char c[20][20];

int dx[4] = { 0, 1, 0, -1 };

int dy[4] = { 1, 0, -1, 0 };

bool used[20][20];



int dfs(int sx, int sy, int px, int py) {

	if (sx == px && sy == py && used[px][py] == true) return 0;

	used[px][py] = true;



	int ret = -10000;

	for (int i = 0; i < 4; i++) {

		int nx = px + dx[i], ny = py + dy[i];

		if (nx < 1 || ny < 1 || nx > H || ny > W || c[nx][ny] == '#') continue;

		if ((sx != nx || sy != ny) && used[nx][ny] == true) continue;

		int v = dfs(sx, sy, nx, ny);

		ret = max(ret, v + 1);

	}

	used[px][py] = false;

	return ret;

}



int main() {

	// Step #1. Input

	cin >> H >> W;

	for (int i = 1; i <= H; i++) {

		for (int j = 1; j <= W; j++) cin >> c[i][j];

	}



	// Step #2. DFS

	int Answer = -1;

	for (int i = 1; i <= H; i++) {

		for (int j = 1; j <= W; j++) {

			Answer = max(Answer, dfs(i, j, i, j));

		}

	}

	if (Answer <= 2) Answer = -1;

	cout << Answer << endl;

	return 0;

}


Python solution: h, w = map(int,input().split())
s = [list(input()) for _ in range(h)]

dist = [[-1] * w for _ in range(h)]
d = ((1, 0), (-1, 0), (0, 1), (0, -1))

def dfs(y: int, x: int, cnt) -> int:
    if dist[y][x] != -1:
        if cnt - dist[y][x] >= 4:
            return cnt - dist[y][x]
        else:
            return -1

    num = -1
    dist[y][x] = cnt
    for dy, dx in d:
        if not (0 <= dy + y <= h - 1 and 0 <= dx + x <= w - 1): continue
        if s[dy + y][dx + x] == "#": continue
        num = max(num, dfs(dy + y, dx + x, cnt + 1))    
    dist[y][x] = -1

    return num

ans = -1
for i in range(h):
    for j in range(w):
        if s[i][j] == "#": continue
        ans = max(ans, dfs(i, j, 0))

print(ans)
AtCoder problem 072

C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;



int H, W;

char c[20][20];

int dx[4] = { 0, 1, 0, -1 };

int dy[4] = { 1, 0, -1, 0 };

bool used[20][20];



int dfs(int sx, int sy, int px, int py) {

	if (sx == px && sy == py && used[px][py] == true) return 0;

	used[px][py] = true;



	int ret = -10000;

	for (int i = 0; i < 4; i++) {

		int nx = px + dx[i], ny = py + dy[i];

		if (nx < 1 || ny < 1 || nx > H || ny > W || c[nx][ny] == '#') continue;

		if ((sx != nx || sy != ny) && used[nx][ny] == true) continue;

		int v = dfs(sx, sy, nx, ny);

		ret = max(ret, v + 1);

	}

	used[px][py] = false;

	return ret;

}



int main() {

	// Step #1. Input

	cin >> H >> W;

	for (int i = 1; i <= H; i++) {

		for (int j = 1; j <= W; j++) cin >> c[i][j];

	}



	// Step #2. DFS

	int Answer = -1;

	for (int i = 1; i <= H; i++) {

		for (int j = 1; j <= W; j++) {

			Answer = max(Answer, dfs(i, j, i, j));

		}

	}

	if (Answer <= 2) Answer = -1;

	cout << Answer << endl;

	return 0;

}






Ruby solution: require 'thread'

State = Struct.new(:vis, :pos, :src)

h, w = readline.split.map(&:to_i)
w += 1
grid = readlines.join + ('#' * w)

queue = Queue.new
dp = {}
for pos in 0...(h * w)
    if grid[pos] == '.' then
        q = State.new(1 << pos, pos, pos)
        queue.push(q)
        dp[q] = 1
    end
end

ans = 2

until queue.empty?
    q0 = queue.pop

    for δ in [-w, -1, +1, +w]
        pos = q0.pos + δ

        next if grid[pos] != '.'
        q1 = State.new(q0.vis | (1 << pos), pos, q0.src)
        next if dp.include?(q1)
        if q1.vis != q0.vis then
            dp[q1] = dp[q0] + 1
            queue.push(q1)
        elsif q1.pos == q0.src then
            ans = [ans, dp[q0]].max
        end
    end
end

puts (ans == 2) ? -1 : ans
AtCoder problem 072

C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;



int H, W;

char c[20][20];

int dx[4] = { 0, 1, 0, -1 };

int dy[4] = { 1, 0, -1, 0 };

bool used[20][20];



int dfs(int sx, int sy, int px, int py) {

	if (sx == px && sy == py && used[px][py] == true) return 0;

	used[px][py] = true;



	int ret = -10000;

	for (int i = 0; i < 4; i++) {

		int nx = px + dx[i], ny = py + dy[i];

		if (nx < 1 || ny < 1 || nx > H || ny > W || c[nx][ny] == '#') continue;

		if ((sx != nx || sy != ny) && used[nx][ny] == true) continue;

		int v = dfs(sx, sy, nx, ny);

		ret = max(ret, v + 1);

	}

	used[px][py] = false;

	return ret;

}



int main() {

	// Step #1. Input

	cin >> H >> W;

	for (int i = 1; i <= H; i++) {

		for (int j = 1; j <= W; j++) cin >> c[i][j];

	}



	// Step #2. DFS

	int Answer = -1;

	for (int i = 1; i <= H; i++) {

		for (int j = 1; j <= W; j++) {

			Answer = max(Answer, dfs(i, j, i, j));

		}

	}

	if (Answer <= 2) Answer = -1;

	cout << Answer << endl;

	return 0;

}





Kuin solution: func main()
	var h: int :: cui@inputInt()
	var w: int :: cui@inputInt()
	var c: [][]char :: #[h][]char
	for i(0, h - 1)
		do c[i] :: cui@input()
	end for
	
	var ans: int :: 0
	if(h = 1 | w = 1)
	else
		for y(0, h - 1)
			for x(0, w - 1)
				for d(0, 3)
					if(c[y][x] = '.')
						do ans :: [ans, f(0, y, x, y, x, h, w, c, d)].max()
					end if
				end for
			end for
		end for
	end if
	if(ans = 0)
		do ans :: -1
	end if
	do cui@print("\{ans}\n")
	
	func f(cnt: int, sy: int, sx: int, y: int, x: int, h: int, w: int, c: [][]char, d: int): int
		var res: int :: 0
		var dx: []int :: [1, 0, -1, 0]
		var dy: []int :: [0, 1, 0, -1]
		for dd(-1, 1)
			var nd: int :: (d + dd + 4) % 4
			var nx: int :: x + dx[nd]
			var ny: int :: y + dy[nd]
			if(nx = -1 | nx = w)
				skip dd
			end if
			if(ny = -1 | ny = h)
				skip dd
			end if
			if(ny = sy & nx = sx)
				do res :: [res, cnt + 1].max()
				skip dd
			end if
			if(c[ny][nx] = '#')
				skip dd
			end if
			do c[ny][nx] :: '#'
			do res :: [res, f(cnt + 1, sy, sx, ny, nx, h, w, c, nd)].max()
			do c[ny][nx] :: '.'
		end for
		ret res
	end func
end func
AtCoder problem 072

C++ solution:


Python solution: h, w = map(int,input().split())
s = [list(input()) for _ in range(h)]

dist = [[-1] * w for _ in range(h)]
d = ((1, 0), (-1, 0), (0, 1), (0, -1))

def dfs(y: int, x: int, cnt) -> int:
    if dist[y][x] != -1:
        if cnt - dist[y][x] >= 4:
            return cnt - dist[y][x]
        else:
            return -1

    num = -1
    dist[y][x] = cnt
    for dy, dx in d:
        if not (0 <= dy + y <= h - 1 and 0 <= dx + x <= w - 1): continue
        if s[dy + y][dx + x] == "#": continue
        num = max(num, dfs(dy + y, dx + x, cnt + 1))    
    dist[y][x] = -1

    return num

ans = -1
for i in range(h):
    for j in range(w):
        if s[i][j] == "#": continue
        ans = max(ans, dfs(i, j, 0))

print(ans)




Ruby solution: require 'thread'

State = Struct.new(:vis, :pos, :src)

h, w = readline.split.map(&:to_i)
w += 1
grid = readlines.join + ('#' * w)

queue = Queue.new
dp = {}
for pos in 0...(h * w)
    if grid[pos] == '.' then
        q = State.new(1 << pos, pos, pos)
        queue.push(q)
        dp[q] = 1
    end
end

ans = 2

until queue.empty?
    q0 = queue.pop

    for δ in [-w, -1, +1, +w]
        pos = q0.pos + δ

        next if grid[pos] != '.'
        q1 = State.new(q0.vis | (1 << pos), pos, q0.src)
        next if dp.include?(q1)
        if q1.vis != q0.vis then
            dp[q1] = dp[q0] + 1
            queue.push(q1)
        elsif q1.pos == q0.src then
            ans = [ans, dp[q0]].max
        end
    end
end

puts (ans == 2) ? -1 : ans
AtCoder problem 072

C++ solution:


Python solution: h, w = map(int,input().split())
s = [list(input()) for _ in range(h)]

dist = [[-1] * w for _ in range(h)]
d = ((1, 0), (-1, 0), (0, 1), (0, -1))

def dfs(y: int, x: int, cnt) -> int:
    if dist[y][x] != -1:
        if cnt - dist[y][x] >= 4:
            return cnt - dist[y][x]
        else:
            return -1

    num = -1
    dist[y][x] = cnt
    for dy, dx in d:
        if not (0 <= dy + y <= h - 1 and 0 <= dx + x <= w - 1): continue
        if s[dy + y][dx + x] == "#": continue
        num = max(num, dfs(dy + y, dx + x, cnt + 1))    
    dist[y][x] = -1

    return num

ans = -1
for i in range(h):
    for j in range(w):
        if s[i][j] == "#": continue
        ans = max(ans, dfs(i, j, 0))

print(ans)



Kuin solution: func main()
	var h: int :: cui@inputInt()
	var w: int :: cui@inputInt()
	var c: [][]char :: #[h][]char
	for i(0, h - 1)
		do c[i] :: cui@input()
	end for
	
	var ans: int :: 0
	if(h = 1 | w = 1)
	else
		for y(0, h - 1)
			for x(0, w - 1)
				for d(0, 3)
					if(c[y][x] = '.')
						do ans :: [ans, f(0, y, x, y, x, h, w, c, d)].max()
					end if
				end for
			end for
		end for
	end if
	if(ans = 0)
		do ans :: -1
	end if
	do cui@print("\{ans}\n")
	
	func f(cnt: int, sy: int, sx: int, y: int, x: int, h: int, w: int, c: [][]char, d: int): int
		var res: int :: 0
		var dx: []int :: [1, 0, -1, 0]
		var dy: []int :: [0, 1, 0, -1]
		for dd(-1, 1)
			var nd: int :: (d + dd + 4) % 4
			var nx: int :: x + dx[nd]
			var ny: int :: y + dy[nd]
			if(nx = -1 | nx = w)
				skip dd
			end if
			if(ny = -1 | ny = h)
				skip dd
			end if
			if(ny = sy & nx = sx)
				do res :: [res, cnt + 1].max()
				skip dd
			end if
			if(c[ny][nx] = '#')
				skip dd
			end if
			do c[ny][nx] :: '#'
			do res :: [res, f(cnt + 1, sy, sx, ny, nx, h, w, c, nd)].max()
			do c[ny][nx] :: '.'
		end for
		ret res
	end func
end func
AtCoder problem 072

C++ solution:





Kuin solution: func main()
	var h: int :: cui@inputInt()
	var w: int :: cui@inputInt()
	var c: [][]char :: #[h][]char
	for i(0, h - 1)
		do c[i] :: cui@input()
	end for
	
	var ans: int :: 0
	if(h = 1 | w = 1)
	else
		for y(0, h - 1)
			for x(0, w - 1)
				for d(0, 3)
					if(c[y][x] = '.')
						do ans :: [ans, f(0, y, x, y, x, h, w, c, d)].max()
					end if
				end for
			end for
		end for
	end if
	if(ans = 0)
		do ans :: -1
	end if
	do cui@print("\{ans}\n")
	
	func f(cnt: int, sy: int, sx: int, y: int, x: int, h: int, w: int, c: [][]char, d: int): int
		var res: int :: 0
		var dx: []int :: [1, 0, -1, 0]
		var dy: []int :: [0, 1, 0, -1]
		for dd(-1, 1)
			var nd: int :: (d + dd + 4) % 4
			var nx: int :: x + dx[nd]
			var ny: int :: y + dy[nd]
			if(nx = -1 | nx = w)
				skip dd
			end if
			if(ny = -1 | ny = h)
				skip dd
			end if
			if(ny = sy & nx = sx)
				do res :: [res, cnt + 1].max()
				skip dd
			end if
			if(c[ny][nx] = '#')
				skip dd
			end if
			do c[ny][nx] :: '#'
			do res :: [res, f(cnt + 1, sy, sx, ny, nx, h, w, c, nd)].max()
			do c[ny][nx] :: '.'
		end for
		ret res
	end func
end func


Ruby solution: require 'thread'

State = Struct.new(:vis, :pos, :src)

h, w = readline.split.map(&:to_i)
w += 1
grid = readlines.join + ('#' * w)

queue = Queue.new
dp = {}
for pos in 0...(h * w)
    if grid[pos] == '.' then
        q = State.new(1 << pos, pos, pos)
        queue.push(q)
        dp[q] = 1
    end
end

ans = 2

until queue.empty?
    q0 = queue.pop

    for δ in [-w, -1, +1, +w]
        pos = q0.pos + δ

        next if grid[pos] != '.'
        q1 = State.new(q0.vis | (1 << pos), pos, q0.src)
        next if dp.include?(q1)
        if q1.vis != q0.vis then
            dp[q1] = dp[q0] + 1
            queue.push(q1)
        elsif q1.pos == q0.src then
            ans = [ans, dp[q0]].max
        end
    end
end

puts (ans == 2) ? -1 : ans
AtCoder problem 073

C++ solution:
#include <iostream>

#include <vector>

using namespace std;



long long N, A[1 << 18], B[1 << 18];

char C[1 << 18];



long long mod = 1000000007;

long long dp[1 << 18][3];

vector<int> G[1 << 18];



void dfs(int pos, int pre) {

	long long val1 = 1, val2 = 1;

	for (int i : G[pos]) {

		if (i == pre) continue;

		dfs(i, pos);

		if (C[pos] == 'a') {

			val1 *= (dp[i][0] + dp[i][2]);

			val2 *= (dp[i][0] + dp[i][1] + 2LL * dp[i][2]);

		}

		if (C[pos] == 'b') {

			val1 *= (dp[i][1] + dp[i][2]);

			val2 *= (dp[i][0] + dp[i][1] + 2LL * dp[i][2]);

		}

		val1 %= mod;

		val2 %= mod;

	}



	if (C[pos] == 'a') {

		dp[pos][0] = val1;

		dp[pos][2] = (val2 - val1 + mod) % mod;

	}

	if (C[pos] == 'b') {

		dp[pos][1] = val1;

		dp[pos][2] = (val2 - val1 + mod) % mod;

	}

}



int main() {

	// Step #1. Input

	cin >> N;

	for (int i = 1; i <= N; i++) cin >> C[i];

	for (int i = 1; i <= N - 1; i++) {

		cin >> A[i] >> B[i];

		G[A[i]].push_back(B[i]);

		G[B[i]].push_back(A[i]);

	}



	// Step #2. DFS

	dfs(1, -1);

	cout << dp[1][2] << endl;

	return 0;

}


Python solution: from collections import deque
n = int(input())
C = input().split()
mod = 10**9+7
e = [[] for i in range(n)]
for _ in range(n-1):
    a,b = [int(x)-1 for x in input().split()]
    e[a].append(b)
    e[b].append(a)
par = [-1]*n
topo = []
q = deque([0])
while q:
    x = q.pop()
    topo.append(x)
    for nex in e[x]:
        if par[x] == nex:
            continue
        par[nex] = x
        q.append(nex)
        
dp = [[-1]*3 for i in range(n)]

for x in topo[::-1]:
    id = int(C[x] == "b")
    dpx = [0]*3
    dpx[id] = 1
    dpx[2] = 1
    for nex in e[x]:
        if nex == par[x]:
            continue
        ndp = dp[nex]
        dpx[id] *= (ndp[id]+ndp[2])
        dpx[id] %= mod
        dpx[2] *= sum(ndp)+ndp[2]
        dpx[2] %= mod
    dpx[2] -= dpx[id]
    dpx[2] %= mod
    dp[x] = dpx

print(dp[0][2])
AtCoder problem 073

C++ solution:

Crystal solution: MOD = 10**9 + 7

class Graph
  def initialize(size, @color : Array(Char))
    @graph = Array(Array(Int32)).new(size) { [] of Int32 }
  end

  def add_edge(u, v)
    @graph[u] << v
    @graph[v] << u
  end

  def run
    dfs(0, -1)[2] % MOD
  end

  def dfs(v, p)
    val1, val2 = 1i64, 1i64
    @graph[v].each do |u|
      next if u == p
      a, b, ab = dfs(u, v)
      val1 *= (@color[v] == 'a' ? a : b) + ab
      val2 *= a + b + ab * 2
      val1 %= MOD
      val2 %= MOD
    end

    if @color[v] == 'a'
      {val1, 0i64, val2 - val1}
    else
      {0i64, val1, val2 - val1}
    end
  end
end

n = read_line.to_i
c = read_line.split.map(&.[0])
g = Graph.new(n, c)
n.pred.times do
  a, b = read_line.split.map(&.to_i.pred)
  g.add_edge(a, b)
end
puts g.run


Python solution: from collections import deque
n = int(input())
C = input().split()
mod = 10**9+7
e = [[] for i in range(n)]
for _ in range(n-1):
    a,b = [int(x)-1 for x in input().split()]
    e[a].append(b)
    e[b].append(a)
par = [-1]*n
topo = []
q = deque([0])
while q:
    x = q.pop()
    topo.append(x)
    for nex in e[x]:
        if par[x] == nex:
            continue
        par[nex] = x
        q.append(nex)
        
dp = [[-1]*3 for i in range(n)]

for x in topo[::-1]:
    id = int(C[x] == "b")
    dpx = [0]*3
    dpx[id] = 1
    dpx[2] = 1
    for nex in e[x]:
        if nex == par[x]:
            continue
        ndp = dp[nex]
        dpx[id] *= (ndp[id]+ndp[2])
        dpx[id] %= mod
        dpx[2] *= sum(ndp)+ndp[2]
        dpx[2] %= mod
    dpx[2] -= dpx[id]
    dpx[2] %= mod
    dp[x] = dpx

print(dp[0][2])
AtCoder problem 073

C++ solution:


Python solution: from collections import deque
n = int(input())
C = input().split()
mod = 10**9+7
e = [[] for i in range(n)]
for _ in range(n-1):
    a,b = [int(x)-1 for x in input().split()]
    e[a].append(b)
    e[b].append(a)
par = [-1]*n
topo = []
q = deque([0])
while q:
    x = q.pop()
    topo.append(x)
    for nex in e[x]:
        if par[x] == nex:
            continue
        par[nex] = x
        q.append(nex)
        
dp = [[-1]*3 for i in range(n)]

for x in topo[::-1]:
    id = int(C[x] == "b")
    dpx = [0]*3
    dpx[id] = 1
    dpx[2] = 1
    for nex in e[x]:
        if nex == par[x]:
            continue
        ndp = dp[nex]
        dpx[id] *= (ndp[id]+ndp[2])
        dpx[id] %= mod
        dpx[2] *= sum(ndp)+ndp[2]
        dpx[2] %= mod
    dpx[2] -= dpx[id]
    dpx[2] %= mod
    dp[x] = dpx

print(dp[0][2])



Kuin solution: var dp: [][]int
var c: []char

func main()
	const mod: int :: 1000000007
	var n: int :: cui@inputInt()
	do @c :: #[n]char
	for i(0, n - 1)
		do @c[i] :: cui@inputChar()
	end for
	var g: []list<int> :: #[n]list<int>
	for i(0, n - 1)
		do g[i] :: #list<int>
	end for
	for(1, n - 1)
		var a: int :: cui@inputInt() - 1
		var b: int :: cui@inputInt() - 1
		do g[a].add(b)
		do g[b].add(a)
	end for
	
	do @dp :: #[n, 3]int
	do dfs(g, 0, -1)
	var ans: int :: @dp[0][2]
	do cui@print("\{ans}\n")
	
	func dfs(g: []list<int>, u: int, p: int)
		var x: int :: @c[u] $ int - 'a' $ int
		do @dp[u][x] :: 1
		do @dp[u][2] :: 1
		do g[u].head()
		for(1, ^g[u])
			var v: int :: g[u].get()
			if(v <> p)
				do dfs(g, v, u)
				var v2: int :: @dp[v][x] + @dp[v][2]
				var v3: int :: @dp[v][0] + @dp[v][1] + 2 * @dp[v][2]
				do @dp[u][x] :* v2
				do @dp[u][x] :% mod
				do @dp[u][2] :* v3
				do @dp[u][2] :% mod
			end if
			do g[u].next()
		end for
		do @dp[u][2] :+ mod - @dp[u][x]
		do @dp[u][2] :% mod
	end func
end func
AtCoder problem 073

C++ solution:
#include <iostream>

#include <vector>

using namespace std;



long long N, A[1 << 18], B[1 << 18];

char C[1 << 18];



long long mod = 1000000007;

long long dp[1 << 18][3];

vector<int> G[1 << 18];



void dfs(int pos, int pre) {

	long long val1 = 1, val2 = 1;

	for (int i : G[pos]) {

		if (i == pre) continue;

		dfs(i, pos);

		if (C[pos] == 'a') {

			val1 *= (dp[i][0] + dp[i][2]);

			val2 *= (dp[i][0] + dp[i][1] + 2LL * dp[i][2]);

		}

		if (C[pos] == 'b') {

			val1 *= (dp[i][1] + dp[i][2]);

			val2 *= (dp[i][0] + dp[i][1] + 2LL * dp[i][2]);

		}

		val1 %= mod;

		val2 %= mod;

	}



	if (C[pos] == 'a') {

		dp[pos][0] = val1;

		dp[pos][2] = (val2 - val1 + mod) % mod;

	}

	if (C[pos] == 'b') {

		dp[pos][1] = val1;

		dp[pos][2] = (val2 - val1 + mod) % mod;

	}

}



int main() {

	// Step #1. Input

	cin >> N;

	for (int i = 1; i <= N; i++) cin >> C[i];

	for (int i = 1; i <= N - 1; i++) {

		cin >> A[i] >> B[i];

		G[A[i]].push_back(B[i]);

		G[B[i]].push_back(A[i]);

	}



	// Step #2. DFS

	dfs(1, -1);

	cout << dp[1][2] << endl;

	return 0;

}

Crystal solution: MOD = 10**9 + 7

class Graph
  def initialize(size, @color : Array(Char))
    @graph = Array(Array(Int32)).new(size) { [] of Int32 }
  end

  def add_edge(u, v)
    @graph[u] << v
    @graph[v] << u
  end

  def run
    dfs(0, -1)[2] % MOD
  end

  def dfs(v, p)
    val1, val2 = 1i64, 1i64
    @graph[v].each do |u|
      next if u == p
      a, b, ab = dfs(u, v)
      val1 *= (@color[v] == 'a' ? a : b) + ab
      val2 *= a + b + ab * 2
      val1 %= MOD
      val2 %= MOD
    end

    if @color[v] == 'a'
      {val1, 0i64, val2 - val1}
    else
      {0i64, val1, val2 - val1}
    end
  end
end

n = read_line.to_i
c = read_line.split.map(&.[0])
g = Graph.new(n, c)
n.pred.times do
  a, b = read_line.split.map(&.to_i.pred)
  g.add_edge(a, b)
end
puts g.run