diff --git a/scripts/import-jacket.sh b/scripts/import-jacket.sh
index 3015918..fc17767 100755
--- a/scripts/import-jacket.sh
+++ b/scripts/import-jacket.sh
@@ -17,8 +17,8 @@ mkdir -p $dir_path
 cd $dir_path
 
 http GET "$url" > temp
-convert ./temp ./base.jpg
-convert ./base.jpg -resize 256x256 ./base_256.jpg
+magick ./temp ./base.jpg
+magick ./base.jpg -resize 256x256 ./base_256.jpg
 rm temp
 img2sixel ./base.jpg
 
diff --git a/scripts/prepare-songs.sh b/scripts/prepare-songs.sh
index 5da442f..5129442 100755
--- a/scripts/prepare-songs.sh
+++ b/scripts/prepare-songs.sh
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-dir_path=$SHIMMERING_DATA_DIR/songs
+dir_path=$SHIMMERING_ASSETS_DIR/songs/raw
 
 # Find all files in the directory and its subdirectories
 find "$dir_path" -type f | while read -r file; do
diff --git a/shimmering/config/charts.csv b/shimmering/config/charts.csv
index e714337..c0a3f3f 100644
--- a/shimmering/config/charts.csv
+++ b/shimmering/config/charts.csv
@@ -629,3 +629,7 @@ Vulcānus,"Team Grimoire
 vs. Aoi",Rotaeno,Volution,PST 5,5.5,968,Volution CCCLX,PRS 8,8.4,"1,234",Volution IV,FTR 10+,10.9,"1,542",N/A,,,,Light,212,5.10.0,24/8/29,N/A,,✓
 epitaxy,Camellia,World Extend 3: Illusions,Dec18,PST 3,3.0,826,Dec18,PRS 6,6.0,939,Dec18,FTR 8,8.6,"1,177",Dec18,ETR 9,9.6,"1,410",Light,183,5.10.0,24/8/29,5.10.0,24/8/29,
 "Rain of Conflict in a Radiant Abyss",ak+q,Memory Archive: Partner,"Nitro ""v20170309""",PST 5,5.0,831,"Nitro ""v20170309""",PRS 7+,7.8,934,"Nitro ""v20170309""",FTR 9,9.5,"1,174","Nitro meets Toaster ""v20170309""",ETR 10,10.5,"1,247",Conflict,195,5.10.2,24/9/12,5.10.2,24/9/12,✓
+Saint or Sinner,crayvxn,Adverse Prelude,小終点,PST 3,3.0,447,小終点,PRS 6,6.0,563,小終点,FTR 8+,8.8,906,N/A,,,,Conflict,164,5.10.4,24/9/26,N/A,,✓
+FURETE-MITAI,みきとP,World Extend 3: Illusions,nora::neko,PST 2,2.5,447,nora::neko,PRS 6,6.0,523,nora::neko,FTR 8,8.4,763,nora::neko,ETR 9,9.4,841,Light,155,5.10.4,24/9/26,5.10.4,24/9/26,
+Hailstone,Kazki Misora,World Extend 3: Illusions,raycast,PST 3,3.5,534,raycast,PRS 7,7.0,651,raycast,FTR 9+,9.7,"1,002",N/A,,,,Light,180,5.10.4,24/9/26,N/A,,
+Gensou no Satellite,豚乙女,Memory Archive: Pop/Recommended,Luxance,PST 2,2.5,721,Luxance,PRS 6,6.5,783,Luxance,FTR 8+,8.7,992,Luxance,ETR 10,10.1,"1,139",Conflict,230,5.10.4,24/9/26,5.10.4,24/9/26,
diff --git a/src/arcaea/chart.rs b/src/arcaea/chart.rs
index fd41a0f..9313e3b 100644
--- a/src/arcaea/chart.rs
+++ b/src/arcaea/chart.rs
@@ -240,7 +240,7 @@ pub struct Chart {
 #[derive(Debug, Clone)]
 pub struct CachedSong {
 	pub song: Song,
-	chart_ids: [Option<NonZeroU16>; 5],
+	chart_ids: [Option<NonZeroU16>; Difficulty::DIFFICULTIES.len()],
 }
 
 impl CachedSong {
@@ -253,8 +253,11 @@ impl CachedSong {
 	}
 
 	#[inline]
-	pub fn charts(&self) -> impl Iterator<Item = u32> {
-		self.chart_ids.into_iter().flatten().map(|i| i.get() as u32)
+	pub fn charts(&self) -> impl Iterator<Item = (Difficulty, u32)> {
+		self.chart_ids
+			.into_iter()
+			.enumerate()
+			.filter_map(|(i, id)| id.map(|id| (Difficulty::DIFFICULTIES[i], id.get() as u32)))
 	}
 }
 // }}}
diff --git a/src/arcaea/jacket.rs b/src/arcaea/jacket.rs
index cf06e0b..a5181ab 100644
--- a/src/arcaea/jacket.rs
+++ b/src/arcaea/jacket.rs
@@ -158,7 +158,7 @@ impl JacketCache {
 							bitmap,
 						});
 					} else {
-						for chart_id in song_cache.lookup_song(song_id)?.charts() {
+						for (_, chart_id) in song_cache.lookup_song(song_id)?.charts() {
 							let chart = song_cache.lookup_chart_mut(chart_id)?;
 							if chart.jacket_source.is_none() {
 								chart.cached_jacket = Some(Jacket {
diff --git a/src/commands/calc.rs b/src/commands/calc.rs
index 663eb9d..b1cbcdc 100644
--- a/src/commands/calc.rs
+++ b/src/commands/calc.rs
@@ -13,7 +13,7 @@ use super::discord::MessageContext;
 // }}}
 
 // {{{ Top command
-/// Compute different things
+/// Compute various things
 #[poise::command(
 	prefix_command,
 	slash_command,
diff --git a/src/commands/chart.rs b/src/commands/chart.rs
index 5c982f0..a8d192a 100644
--- a/src/commands/chart.rs
+++ b/src/commands/chart.rs
@@ -24,7 +24,7 @@ use super::discord::{CreateReplyExtra, MessageContext};
 // }}}
 
 // {{{ Top command
-/// Chart-related stats
+/// Chart-related utilities.
 #[poise::command(
 	prefix_command,
 	slash_command,
diff --git a/src/commands/score.rs b/src/commands/score.rs
index 97e9846..6e153ca 100644
--- a/src/commands/score.rs
+++ b/src/commands/score.rs
@@ -323,7 +323,7 @@ mod show_tests {
 }
 // }}}
 // {{{ Discord wrapper
-/// Show scores given their ides
+/// Show scores given their IDs.
 #[poise::command(prefix_command, slash_command)]
 pub async fn show(
 	mut ctx: Context<'_>,
diff --git a/src/commands/stats.rs b/src/commands/stats.rs
index 6cdf217..731b1e1 100644
--- a/src/commands/stats.rs
+++ b/src/commands/stats.rs
@@ -26,7 +26,7 @@ use super::discord::MessageContext;
 // }}}
 
 // {{{ Stats
-/// Stats display
+/// Query various stats.
 #[poise::command(
 	prefix_command,
 	slash_command,
diff --git a/src/recognition/fuzzy_song_name.rs b/src/recognition/fuzzy_song_name.rs
index a8fda98..b3a2969 100644
--- a/src/recognition/fuzzy_song_name.rs
+++ b/src/recognition/fuzzy_song_name.rs
@@ -80,8 +80,16 @@ pub fn guess_chart_name<'a>(
 				let plausible_difficulty = match difficulty {
 					Some(difficulty) => difficulty == chart.difficulty,
 					None => {
-						let chart_count = cached_song.charts().count();
-						chart_count == 1 || chart.difficulty == Difficulty::FTR
+						let has_ftr = cached_song.charts().any(|(d, _)| d == Difficulty::FTR);
+						let main_diff = if has_ftr {
+							Difficulty::FTR
+						} else {
+							let (max_diff, _) =
+								cached_song.charts().max_by_key(|(d, _)| *d).unwrap();
+							max_diff
+						};
+
+						chart.difficulty == main_diff
 					}
 				};