```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Read number of chats
line, err := reader.ReadString('\n')
if err != nil {
return
}
tStr := strings.TrimSpace(line)
if tStr == "" {
return
}
t, _ := strconv.Atoi(tStr)
for i := 0; i < t; i++ {
solve(reader)
}
}
// Helper to check if a character is alphanumeric
func isAlphaNum(r rune) bool {
return (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9')
}
func solve(reader *bufio.Reader) {
// Read number of users
line, _ := reader.ReadString('\n')
n, _ := strconv.Atoi(strings.TrimSpace(line))
// Read usernames
line, _ = reader.ReadString('\n')
users := strings.Fields(line)
userMap := make(map[string]int)
for idx, u := range users {
userMap[u] = idx
}
// Read number of messages
line, _ = reader.ReadString('\n')
m, _ := strconv.Atoi(strings.TrimSpace(line))
type Message struct {
SenderID int // -1 if unknown
Text string
Mentions []bool
}
msgs := make([]Message, m)
for k := 0; k < m; k++ {
line, _ = reader.ReadString('\n')
line = strings.TrimSpace(line)
parts := strings.SplitN(line, ":", 2)
senderName := parts[0]
text := parts[1]
sID := -1
if senderName != "?" {
sID = userMap[senderName]
}
mentions := make([]bool, n)
// Parse text to identify mentions
var sb strings.Builder
for _, r := range text {
if isAlphaNum(r) {
sb.WriteRune(r)
} else {
sb.WriteRune(' ')
}
}
// Split by whitespace to get potential username tokens
words := strings.Fields(sb.String())
for _, w := range words {
if id, ok := userMap[w]; ok {
mentions[id] = true
}
}
msgs[k] = Message{
SenderID: sID,
Text: text,
Mentions: mentions,
}
}
// Dynamic Programming
// dp[k][u] means is it possible for message k to be sent by user u
dp := make([][]bool, m)
parent := make([][]int, m)
for k := 0; k < m; k++ {
dp[k] = make([]bool, n)
parent[k] = make([]int, n)
}
// Initialization for the first message
for u := 0; u < n; u++ {
if msgs[0].SenderID != -1 && msgs[0].SenderID != u {
continue
}
if msgs[0].Mentions[u] {
continue
}
dp[0][u] = true
parent[0][u] = -1
}
// Fill DP table
for k := 1; k < m; k++ {
for u := 0; u < n; u++ {
// Check if user u is a valid sender for message k
if msgs[k].SenderID != -1 && msgs[k].SenderID != u {
continue
}
if msgs[k].Mentions[u] {
continue
}
// Try to find a valid previous sender (cannot be the same user)
for prev := 0; prev < n; prev++ {
if prev != u && dp[k-1][prev] {
dp[k][u] = true
parent[k][u] = prev
break // Found one valid path, no need to check others
}
}
}
}
// Find if any user is a valid sender for the last message
lastUser := -1
for u := 0; u < n; u++ {
if dp[m-1][u] {
lastUser = u
break
}
}
if lastUser == -1 {
fmt.Println("Impossible")
} else {
// Reconstruct path
result := make([]int, m)
curr := lastUser
for k := m - 1; k >= 0; k-- {
result[k] = curr
curr = parent[k][curr]
}
// Output result
for k := 0; k < m; k++ {
fmt.Printf("%s:%s\n", users[result[k]], msgs[k].Text)
}
}
}
```