diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 7832cb522c4ac8000dddd861b8eedbfd1916b434..d7cd0575b73caa2f3140644fff5e1a780cf4ab46 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -408,8 +408,6 @@ public class Suggest implements Dictionary.WordCallback {
             final String typedWord, final ArrayList<SuggestedWordInfo> suggestions) {
         final SuggestedWordInfo typedWordInfo = suggestions.get(0);
         typedWordInfo.setDebugString("+");
-        double normalizedScore = BinaryDictionary.calcNormalizedScore(
-                typedWord, typedWordInfo.toString(), typedWordInfo.mScore);
         final int suggestionsSize = suggestions.size();
         final ArrayList<SuggestedWordInfo> suggestionsList =
                 new ArrayList<SuggestedWordInfo>(suggestionsSize);
@@ -418,10 +416,11 @@ public class Suggest implements Dictionary.WordCallback {
         // than i because we added the typed word to mSuggestions without touching mScores.
         for (int i = 0; i < suggestionsSize - 1; ++i) {
             final SuggestedWordInfo cur = suggestions.get(i + 1);
+            final double normalizedScore = BinaryDictionary.calcNormalizedScore(
+                    typedWord, cur.toString(), cur.mScore);
             final String scoreInfoString;
             if (normalizedScore > 0) {
                 scoreInfoString = String.format("%d (%4.2f)", cur.mScore, normalizedScore);
-                normalizedScore = 0.0;
             } else {
                 scoreInfoString = Integer.toString(cur.mScore);
             }
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index 9234b1b52d9e7e766de3da14011ad749f5acd84f..43fe892be3449ce15e9065291f9f4a58db06e74d 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -208,7 +208,8 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo,
         AKLOGI("Max normalized score = %f", ns);
     }
     const int suggestedWordsCount =
-            queuePool->getMasterQueue()->outputSuggestions(frequencies, outWords);
+            queuePool->getMasterQueue()->outputSuggestions(
+                    proximityInfo->getPrimaryInputWord(), codesSize, frequencies, outWords);
 
     if (DEBUG_DICT) {
         double ns = queuePool->getMasterQueue()->getHighestNormalizedScore(
diff --git a/native/jni/src/words_priority_queue.h b/native/jni/src/words_priority_queue.h
index 249962eec0592132c322a69ec0022f6ea8589dc0..1387267a0157df6fd9bdca6d48749da8348acdd9 100644
--- a/native/jni/src/words_priority_queue.h
+++ b/native/jni/src/words_priority_queue.h
@@ -92,10 +92,12 @@ class WordsPriorityQueue {
         return sw;
     }
 
-    int outputSuggestions(int *frequencies, unsigned short *outputChars) {
+    int outputSuggestions(const unsigned short* before, const int beforeLength,
+            int *frequencies, unsigned short *outputChars) {
         mHighestSuggestedWord = 0;
         const unsigned int size = min(
               MAX_WORDS, static_cast<unsigned int>(mSuggestions.size()));
+        SuggestedWord* swBuffer[size];
         int index = size - 1;
         while (!mSuggestions.empty() && index >= 0) {
             SuggestedWord* sw = mSuggestions.top();
@@ -103,17 +105,45 @@ class WordsPriorityQueue {
                 AKLOGI("dump word. %d", sw->mScore);
                 DUMP_WORD(sw->mWord, sw->mWordLength);
             }
+            swBuffer[index] = sw;
+            mSuggestions.pop();
+            --index;
+        }
+        if (size >= 2) {
+            SuggestedWord* nsMaxSw = 0;
+            unsigned int maxIndex = 0;
+            double maxNs = 0;
+            for (unsigned int i = 0; i < size; ++i) {
+                SuggestedWord* tempSw = swBuffer[i];
+                if (!tempSw) {
+                    continue;
+                }
+                const double tempNs = getNormalizedScore(tempSw, before, beforeLength, 0, 0, 0);
+                if (tempNs >= maxNs) {
+                    maxNs = tempNs;
+                    maxIndex = i;
+                    nsMaxSw = tempSw;
+                }
+            }
+            if (maxIndex > 0 && nsMaxSw) {
+                memmove(&swBuffer[1], &swBuffer[0], maxIndex * sizeof(SuggestedWord*));
+                swBuffer[0] = nsMaxSw;
+            }
+        }
+        for (unsigned int i = 0; i < size; ++i) {
+            SuggestedWord* sw = swBuffer[i];
+            if (!sw) {
+                AKLOGE("SuggestedWord is null %d", i);
+                continue;
+            }
             const unsigned int wordLength = sw->mWordLength;
-            char* targetAdr = (char*) outputChars
-                    + (index) * MAX_WORD_LENGTH * sizeof(short);
-            frequencies[index] = sw->mScore;
+            char* targetAdr = (char*) outputChars + i * MAX_WORD_LENGTH * sizeof(short);
+            frequencies[i] = sw->mScore;
             memcpy(targetAdr, sw->mWord, (wordLength) * sizeof(short));
             if (wordLength < MAX_WORD_LENGTH) {
                 ((unsigned short*) targetAdr)[wordLength] = 0;
             }
             sw->mUsed = false;
-            mSuggestions.pop();
-            --index;
         }
         return size;
     }
@@ -147,21 +177,8 @@ class WordsPriorityQueue {
         if (!mHighestSuggestedWord) {
             return 0.0;
         }
-        SuggestedWord* sw = mHighestSuggestedWord;
-        const int score = sw->mScore;
-        unsigned short* word = sw->mWord;
-        const int wordLength = sw->mWordLength;
-        if (outScore) {
-            *outScore = score;
-        }
-        if (outWord) {
-            *outWord = word;
-        }
-        if (outLength) {
-            *outLength = wordLength;
-        }
-        return Correction::RankingAlgorithm::calcNormalizedScore(
-                before, beforeLength, word, wordLength, score);
+        return getNormalizedScore(
+                mHighestSuggestedWord, before, beforeLength, outWord, outScore, outLength);
     }
 
  private:
@@ -182,6 +199,24 @@ class WordsPriorityQueue {
         return 0;
     }
 
+    static double getNormalizedScore(SuggestedWord* sw, const unsigned short* before,
+            const int beforeLength, unsigned short** outWord, int *outScore, int *outLength) {
+        const int score = sw->mScore;
+        unsigned short* word = sw->mWord;
+        const int wordLength = sw->mWordLength;
+        if (outScore) {
+            *outScore = score;
+        }
+        if (outWord) {
+            *outWord = word;
+        }
+        if (outLength) {
+            *outLength = wordLength;
+        }
+        return Correction::RankingAlgorithm::calcNormalizedScore(
+                before, beforeLength, word, wordLength, score);
+    }
+
     typedef std::priority_queue<SuggestedWord*, std::vector<SuggestedWord*>,
             wordComparator> Suggestions;
     Suggestions mSuggestions;