* @param a
     * @param numThreads number of threads to use; 1 means run on the current thread
     */
    private static void squareElements(final MutableModFn[] a, int numThreads) {
        if (numThreads > 1) {
            ExecutorService executor = Executors.newFixedThreadPool(numThreads);
            Collection<Future<?>> pending = new ArrayList<>();
            for (int i=0; i<numThreads; i++) {
                final int fromIdx = a.length * i / numThreads;
                final int toIdx = a.length * (i+1) / numThreads;
                Future<?> future = executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        for (int idx=fromIdx; idx<toIdx; idx++)
                            a[idx].square();
                    }
                });
                pending.add(future);
            }
            executor.shutdown();
            try {
                for (Future<?> future: pending)
                    future.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new ArithmeticException(e.getLocalizedMessage());
            }
        }
        else
            for (int i=0; i<a.length; i++)
                a[i].square();
    }