Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java	(revision 16197)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java	(working copy)
@@ -447,6 +447,7 @@
     public static class IndexCondition implements Condition {
         final String index;
         final Op op;
+        final boolean isFirstOrLast;
 
         /**
          * Constructs a new {@code IndexCondition}.
@@ -456,6 +457,7 @@
         public IndexCondition(String index, Op op) {
             this.index = index;
             this.op = op;
+            isFirstOrLast = op == Op.EQ && ("1".equals(index) || "-1".equals(index));
         }
 
         @Override
Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 16197)
+++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(working copy)
@@ -34,6 +34,7 @@
 import org.openstreetmap.josm.data.validation.tests.CrossingWays;
 import org.openstreetmap.josm.gui.mappaint.Environment;
 import org.openstreetmap.josm.gui.mappaint.Range;
+import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.IndexCondition;
 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.OpenEndPseudoClassCondition;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.CompositeList;
@@ -219,7 +220,17 @@
                     e.count = count;
                     return;
                 }
-                for (int i = 0; i < count; i++) {
+                // see #18964
+                boolean firstAndLastOnly = true;
+                for (Condition c : link.conds) {
+                    if (!(c instanceof IndexCondition) || !((IndexCondition) c).isFirstOrLast) {
+                        firstAndLastOnly = false;
+                        break;
+                    }
+                }
+                int step = firstAndLastOnly ? count - 1 : 1;
+
+                for (int i = 0; i < count; i += step) {
                     if (getter.apply(i).equals(e.osm) && link.matches(e.withParentAndIndexAndLinkContext(parent, i, count))) {
                         e.parent = parent;
                         e.index = i;
